Fix glossary auto-linker nesting buttons (hydration error)#1032
Draft
jerelvelarde wants to merge 1 commit into
Draft
Fix glossary auto-linker nesting buttons (hydration error)#1032jerelvelarde wants to merge 1 commit into
jerelvelarde wants to merge 1 commit into
Conversation
remark-glossary wraps each matched term in a <GlossaryTerm>, which renders a <button> (popover trigger). When a term matched mid-sentence (non-empty leading text), the visitor returned a bare SKIP after splicing, so unist-util-visit descended into the just-created GlossaryTerm and re-wrapped a shorter contained term (e.g. "agent" inside "agent runtime"). That nests a <button> in a <button> — invalid HTML that throws a React hydration error. Guard the text visitor so it never re-processes text already inside a GlossaryTerm. Trailing text after a wrapped term is still scanned, so term coverage is unchanged. Add tests/remark-glossary.test.ts with a fixture glossary covering the nested-term case (fails before this change) and confirming terms are still linked. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@jerelvelarde is attempting to deploy a commit to the Arcade AI Team on Vercel. A member of the Team first needs to authorize it. |
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.
What this PR does
Fixes a bug in the glossary auto-linker (
lib/remark-glossary.ts) that produces a<button>nested inside a<button>— invalid HTML that throws a React hydration error in the browser.Root cause
remarkGlossarywraps each matched glossary term in a<GlossaryTerm>, which renders a<button>(the popover trigger). The text visitor matches a term, splices[before, <GlossaryTerm>, after]into the parent's children, and returns a bareSKIP.When the term is matched mid-sentence (non-empty leading text),
SKIPlandsunist-util-visiton the newly-inserted<GlossaryTerm>node and descends into it. Its inner text is then re-scanned, and a shorter term contained in the matched text gets wrapped again — e.g.agentinsideagent runtime— nesting oneGlossaryTerm(button) inside another.This only triggers when a multi-word term that contains a shorter term appears mid-sentence, which is why most pages don't hit it but a term-dense page can hit it several times.
The fix
Guard the text visitor so it never re-processes text already inside a
GlossaryTermit just inserted:This preserves existing behavior (trailing text after a wrapped term is still scanned for other terms) and only prevents the invalid nesting.
Test
Adds
tests/remark-glossary.test.tswith a fixture glossary (tests/fixtures/glossary-nesting.mdx) whereagent runtimecontainsagent. Two cases:GlossaryTermis ever nested inside another.The second test fails on the current code (reproduces the bug) and passes with the fix. Full suite stays green.
cc @thierrypdamiba
🤖 Generated with Claude Code