If your React site uses SSG/SSR with a collapsible accordion for FAQs and you have FAQPage JSON-LD schema, Google sees answers in your schema that don’t exist in your HTML. That’s a structured data violation. The fix is one line. We caught it on HomeCalc.ca — impressions went from 486 to 2,330 in 7 days after the fix.
This bug sits at the intersection of three things that are individually correct but catastrophic together: a React accordion component, server-side rendering, and FAQPage structured data.
Here’s the chain of events:
1. You add an FAQ section with a collapsible accordion — Radix UI, Headless UI, Shadcn, or any component that toggles visibility. Users click a question, the answer expands. Standard UX pattern.
2. The accordion’s default behavior is to remove children from the DOM when collapsed. When state="closed", the answer text isn’t hidden — it’s gone. The DOM node is empty. This is how most React accordion libraries work by default, because it’s more performant than keeping off-screen content mounted.
3. SSG/SSR captures the closed state. When Next.js (or Gatsby, Remix, Astro) pre-renders the page, it runs the component with its default state — which is closed. The generated HTML contains the question text and an empty answer container:
<div data-state="closed" hidden="">
<!-- no answer text here -->
</div>4. But your JSON-LD says the answers exist. Your FAQPage schema — sitting in a <script type="application/ld+json"> tag — correctly contains every question and every answer. Because the schema is generated from a data array, not from the DOM, it doesn’t know the accordion ate the content.
5. Google sees a mismatch. Google’s structured data guidelines are explicit: the content in your schema must match the content visible on the page. Googlebot renders the page, finds FAQPage schema with 5 answers, but the HTML body contains 5 questions and 0 answers. This is a structured data policy violation.
The result: rich result removal, ranking demotion, and a drop in impressions that looks like an algorithm update — but is actually your own code.
This bug is dangerous because every signal says everything is fine:
The UX is perfect. Users click a question, the answer expands. JavaScript hydrates and the accordion works exactly as designed. No user will ever report this as a bug.
The build passes. No TypeScript errors, no lint failures, no broken tests. The component is functioning correctly by its own definition — the default state is closed, and closed means unmounted.
Google’s Rich Results Test may still pass. The test validates schema syntax, not content parity. Your FAQPage schema is syntactically valid. The violation is semantic — the content it describes isn’t in the DOM.
The traffic drop looks algorithmic. When impressions fall 50–75% over a week, the first instinct is “Google algorithm update.” You check industry forums. Other people are complaining too. You assume it’s external. Months pass.
The only way to catch this is to inspect the raw HTML your server generates — not the JavaScript-hydrated page in your browser, but the actual HTML that Googlebot receives on first request.
Open a terminal. Replace the URL with any page on your site that has an FAQ accordion and FAQPage schema.
Step 1: Grab the server-rendered HTML
curl -s https://your-domain.com/page-with-faq > page.htmlStep 2: Search for an FAQ answer
Pick a unique phrase from one of your FAQ answers — something specific enough to not appear elsewhere on the page.
# On Mac/Linux:
grep "your unique answer phrase" page.html
# On Windows PowerShell:
Select-String "your unique answer phrase" page.htmlReading the result
If the answer appears only inside <script type="application/ld+json"> — you have the bug. The schema contains answers that aren’t in the visible HTML. Google sees a mismatch.
If the answer appears outside the script tag too (in a <p> or <div> in the page body) — you’re clean. Your accordion is rendering content in the DOM regardless of collapsed state.
The principle: keep FAQ answer content in the DOM at all times. Use CSS to hide it visually when collapsed — not JavaScript to unmount it.
Radix UI Accordion
Add forceMount to the Content component and use a CSS class to hide it when closed:
<AccordionPrimitive.Content
forceMount
className="data-[state=closed]:hidden"
>
{children}
</AccordionPrimitive.Content>forceMount keeps the content in the DOM regardless of accordion state. The Tailwind class data-[state=closed]:hidden applies display: none visually. The user sees the same collapse/expand UX. Google sees the full content.
Headless UI Disclosure
<Disclosure.Panel static>
{/* answer content */}
</Disclosure.Panel>The static prop keeps the panel mounted in the DOM at all times.
Custom collapsible component
If you built your own accordion: make sure children render into the DOM even when the accordion is closed. Use display: none or visibility: hidden via CSS — never conditionally unmount the content.
Alternative: skip the accordion entirely
The safest approach is to render FAQ content as plain visible HTML — no accordion at all. This is what we do on hamitahm.com: every FAQ section renders as static <h3> + <p> pairs. No accordion, no risk. The content is always in the DOM, always crawlable, always matching the schema.
We discovered this bug on HomeCalc.ca — a Canadian mortgage calculator that went from zero to over 1,100 AI citations in its first 30 days. The site uses Next.js with SSG and had FAQ sections on multiple calculator pages.
Before the fix: 7-day impressions had dropped to 486. Average position was degrading. FAQ-heavy calculator pages were hit hardest. Rich Results for FAQPage had disappeared from Search Console.
The fix: One prop change — forceMount on the Radix Accordion Content component — plus a CSS class to maintain the visual collapse behavior.
After the fix:7-day impressions went from 486 to 2,330 — a 4.8× increase. Recovery started within 3 days. By day 7, impressions exceeded the pre-regression peak. Rich Results returned in Search Console.
Day 4–7: Impressions begin ramping. Rich Results return in Search Console validation.
Day 7–10: Full recovery. In our case, impressions surpassed the pre-bug baseline.
You’re at risk if all three of these are true:
1. Your site uses SSG or SSR (Next.js, Gatsby, Remix, Astro, Nuxt, SvelteKit — any framework that pre-renders HTML on the server).
2. You have FAQ sections using a collapsible accordion or disclosure component (Radix UI, Headless UI, Shadcn/ui, Chakra UI, MUI Accordion, or any custom implementation that unmounts children when collapsed).
3. You have FAQPage JSON-LD schema on those same pages.
If only two of three are true, you’re likely fine. A static site with an accordion but no FAQPage schema has no mismatch to trigger. A site with FAQPage schema but no accordion renders the answers in the DOM. An SPA with an accordion has different rendering behavior — Googlebot runs JavaScript on SPAs and may see the expanded content (though SPAs have their own AI visibility challenges).
The lethal combination is SSG/SSR + collapsible accordion + FAQPage schema. And it’s extremely common in modern React marketing sites, SaaS landing pages, and tool pages.
Not sure what else your site is hiding from Google?
The AI Visibility Audit checks structured data parity, cross-platform citation coverage, competitor gaps, and 40+ other technical signals. Bugs like this one are caught in every audit.
Book an AI Visibility Audit →Does this bug affect Next.js sites specifically?
It affects any React framework that does SSG or SSR — Next.js, Remix, Gatsby, Astro with React islands. The issue is that the accordion component removes children from the DOM when collapsed, and the server render captures that collapsed state. Next.js is the most common framework where this appears because of its SSG/SSR defaults.
How do I know if my FAQ accordion has this bug?
Run curl on your live URL and search for one of your FAQ answer texts in the HTML output. If the answer only appears inside a <script type="application/ld+json"> tag and not in the visible HTML body, your accordion is stripping the content. Two commands: curl your page, then grep for a unique phrase from one of your FAQ answers.
Will Google penalize me for mismatched schema and visible content?
Google's structured data guidelines require that schema content matches what's visible on the page. When FAQPage schema contains answers that aren't in the rendered HTML, Google treats this as a structured data policy violation. The result is rich result removal and ranking demotion — not a manual action, but an algorithmic one that's harder to detect.
How long does recovery take after fixing this bug?
Based on our data from HomeCalc.ca, recovery begins within 3–5 days of deploying the fix. Full recovery to pre-regression levels took approximately 7–10 days. Our 7-day impressions went from 486 to 2,330 after the fix — a 4.8× increase that exceeded the pre-bug baseline.
Does this affect AI visibility too, or just traditional SEO?
Both. AI systems like ChatGPT, Perplexity, and Google's AI Overviews rely on crawlable, structured content to generate citations. If your FAQ answers aren't in the DOM, AI crawlers can't extract them either. The schema says you have answers, but the page doesn't deliver them — so AI systems skip your content entirely.
For more on how AI systems discover and cite your content, see the AI visibility hub. For the full HomeCalc story, read the case study.
Hami Tahm is an AI visibility consultant based in Toronto.