Fix Sandpack navigation for internal markdown links - #9
Merged
Merged
Conversation
Sandpack's preview iframe intercepts real anchor clicks and resolves the href against its own bundler origin, even though the onClick handler already calls preventDefault(). Internal concept links now use href="#" (matching the hrefless <button> pattern already used for backlinks) so the sandbox has nothing real to navigate to, while onSelect() still drives in-app navigation. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
🟢 Approval recommended
The change is narrowly scoped to internal link rendering, aligns with the stated Sandpack root cause, and includes an updated test assertion covering the new markup.
Pull request overview
This PR fixes internal markdown link navigation inside the Sandpack preview by preventing Sandpack from resolving “real” internal href values against its bundler origin, while still allowing in-app navigation via onSelect().
Changes:
- Render resolved internal markdown links with
href="#"(instead of the markdown path) and keep navigation driven by the click handler. - Update the
Detailrendering test assertion to match the new internal link markup.
File summaries
| File | Description |
|---|---|
| src/Detail.jsx | Changes internal markdown link rendering to use href="#" to avoid Sandpack iframe navigation interception while still calling onSelect(target). |
| src/Detail.test.js | Updates expected HTML to assert the new internal link href="#" output. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Internal concept links rendered from markdown bodies (e.g.
[agent second brain](/projects/second-brain.md)) worked in normal Vite rendering but broke in the Sandpack viewer: clicking them navigated to ahttps://bundler.sandbox.animaapp.com/<path>URL instead of switching the in-app selection.The "Cited by" backlinks worked fine in both environments because they're rendered as
<button>elements with nohref.Root cause
Detail.jsx'sMarkdownLinkrendered internal links as<a href={href} onClick={...preventDefault...}>. In normal renderingpreventDefault()is sufficient. Inside Sandpack's preview iframe, the sandbox's own runtime intercepts anchor clicks and resolves the anchor's realhrefagainst its own bundler origin, independent of ourpreventDefault()call — producing the broken bundler URL.Fix
Internal (resolved) links now use
href="#"instead of the real markdown path, mirroring the already-working hrefless<button>pattern used for backlinks.onSelect()still drives navigation via theonClickhandler; the sandbox now has no real path to intercept and navigate to. External links are unaffected.Testing
npm test(22/22 passing), including an updated assertion inDetail.test.jsfor the newhref="#"internal link markup.Made with Cursor