feat: navigate to heading from search results#94
Conversation
Append #slug to URL for heading matches so clicking a search result scrolls directly to the matched heading. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (2)
📝 WalkthroughSummary by CodeRabbit
WalkthroughSearch results for heading matches now include stable URL fragments. The search API uses ChangesHeading Fragment Support
🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
Critical
-
Custom
slugifydoesn't matchgithub-slugger— fumadocs usesgithub-slugger(viaremark-heading.js) to generate headingidattributes in the rendered HTML. The PR introduces a customslugifyfunction that behaves differently. Key differences:github-sluggerpreserves non-ASCII characters (e.g., accented letters, CJK); the custom regex/[^\w\s-]/gstrips them.github-sluggerhandles duplicate headings by appending-1,-2, etc. The custom function doesn't.github-sluggerconverts spaces differently for certain edge cases.
This means clicking a heading search result will navigate to
#wrong-slugand the page won't scroll to the heading. Usegithub-sluggerdirectly — it's already a transitive dependency via fumadocs-core:import Slugger from 'github-slugger'; const slugger = new Slugger(); // reset per document, then: slugger.slug(headingText)
-
Duplicate heading disambiguation is missing — If a page has two headings with the same text (e.g., two "Example" headings),
github-sluggergenerates#exampleand#example-1. The customslugifygenerates#examplefor both, so the second heading result would scroll to the wrong one. Usinggithub-sluggerwith proper per-document reset fixes this.
Issues
-
Slugger state must be per-document, not per-heading —
github-sluggertracks seen slugs to deduplicate. If you create one slugger instance and use it across all documents in the search results, the dedup counter will carry across pages. You need to instantiate a newSlugger()(or callslugger.reset()) for each document/page when building the index. The correct place to compute heading slugs is duringbuildDocs(indexing time), not infindMatch(query time), since you need the full list of headings per page to get dedup right. -
deduplicateByUrlin search.tsx strips anchors — The client-sidededuplicateByUrlfunction (line 188-196) doesr.url.split('#')[0]and deduplicates by the base URL. This means if the same page has two heading matches, only the first one survives. Before this PR that was fine (all results for one page had the same URL), but now heading results have distinct#anchorURLs and should probably not be deduplicated against each other. Consider deduplicating by the full URL (with anchor) when match type isheading, or removing the dedup for heading results.
Minor
-
Headings in the search index may contain markdown formatting — The heading extraction regex
line.match(/^#{1,6}\s+(.+)/)captures raw markdown text. A heading like## Using \config.yaml`stores the backticks in the headings column. The custom slugify strips them, butgithub-sluggerwould produce a different slug than the rendered HTML where backticks become` and are stripped during flattening. Consider stripping inline markdown formatting before slugifying. -
Body match could also benefit from anchor links — If the query matches body text near a heading, you could include the nearest preceding heading's anchor. Not required for this PR but would be a good follow-up.
Replace inline slugify with github-slugger to match fumadocs heading ID generation exactly. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Summary
#sluganchor in URLTest plan
#anchor🤖 Generated with Claude Code