Conversation
Blog posts are rendered from WordPress HTML and can cover multiple features in a single article. Add slugified ids and hover-visible anchor links to every heading so sections can be deep-linked, and introduce an optional blogFragment field on features so a feature can point at a specific section of a multi-topic post.
Wire features 15 (Professional recordings & screenshots) and 28 (Build Insights) to their matching sections in the AI prompts + recording metadata blog post, and add a new Network AI Prompts feature entry on the networking page (hidden from the homepage) that deep-links to the prompt export section.
ab255c8 to
6be21b3
Compare
There was a problem hiding this comment.
Pull request overview
Adds linkable heading anchors to blog posts and enables feature cards to deep-link to specific blog sections (fragments), addressing the referenced issue.
Changes:
- Injects anchor links + IDs into rendered blog post headings and adds styling for the heading-anchor UI.
- Extends the
featurecollection schema/content to supportblogFragmentand updates Feature component link building. - Adds
github-sluggerdependency for consistent heading ID generation.
Reviewed changes
Copilot reviewed 5 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/src/pages/blog/[slug].astro | Generates stable heading IDs and prepends “link to section” anchors; adds CSS for anchor visibility/positioning. |
| docs/src/layouts/components/Feature.astro | Appends an optional #blogFragment to blog links for feature cards. |
| docs/src/content.config.ts | Extends the feature collection schema with optional blogFragment. |
| docs/src/collections/feature/15-professional-captures.md | Adds blogId + blogFragment metadata for deep-linking. |
| docs/src/collections/feature/28-build-insights-inapp.md | Adds blogId + blogFragment metadata for deep-linking. |
| docs/src/collections/feature/31-network-ai-prompts.md | New feature entry including blogId + blogFragment. |
| docs/package.json | Adds github-slugger. |
| docs/package-lock.json | Locks github-slugger dependency resolution. |
Files not reviewed (1)
- docs/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const slugger = new GithubSlugger(); | ||
| const headings = doc.querySelectorAll("h1, h2, h3, h4, h5, h6"); | ||
| const linkIconMarkup = renderToStaticMarkup( | ||
| createElement(FaLink, { "aria-hidden": true }), | ||
| ); | ||
|
|
||
| headings.forEach((heading) => { | ||
| const text = heading.textContent?.trim() ?? ""; | ||
| if (!text) return; | ||
|
|
||
| const id = heading.id || slugger.slug(text); | ||
| heading.id = id; |
There was a problem hiding this comment.
When a heading already has an explicit id, the slugger never sees/records it. If a later heading’s generated slug matches a previously-existing id (or vice versa), this can create duplicate IDs in the document and broken fragment navigation. Consider “reserving” any existing heading IDs with the slugger (or running all IDs through a single uniqueness mechanism) so generated IDs can’t collide with author-provided ones.
| ); | ||
| const { slug } = (await res.json()) as { slug: string }; | ||
| blogPath = `/blog/${slug}`; | ||
| blogPath = `/blog/${slug}${blogFragment ? `#${blogFragment}` : ""}`; |
There was a problem hiding this comment.
blogFragment is interpolated directly into the URL fragment. If it contains characters that need encoding (spaces, %, #, etc.) the generated link can be invalid or point to the wrong anchor. Encode/normalize the fragment (and optionally strip a leading #) before appending it.
| blogPath = `/blog/${slug}${blogFragment ? `#${blogFragment}` : ""}`; | |
| const normalizedBlogFragment = blogFragment | |
| ? (() => { | |
| const fragment = blogFragment.replace(/^#/, ""); | |
| return fragment ? `#${encodeURIComponent(fragment)}` : ""; | |
| })() | |
| : ""; | |
| blogPath = `/blog/${slug}${normalizedBlogFragment}`; |
Closes: https://github.com/AvdLee/LicenseKit/issues/600