Report #63974
[bug\_fix] Prop className did not match or Flash of Unstyled Content \(FOUC\) with styled-components/emotion in App Router
Implement a Styled Components Registry using React.cache and useServerInsertedHTML to collect styles during SSR and inject them into the document head, ensuring the style tag is present in the initial HTML and class names are synchronized.
Journey Context:
Developer migrates from Next.js Pages Router to App Router and keeps using styled-components. They configure the babel plugin as before, but on page load they see a flash of unstyled content and the console shows "Warning: Prop className did not match. Server: 'sc-xxx' Client: 'sc-yyy'". They check the HTML source and see the styled-components styles are missing from the head, causing the server to render with different class names than the client expects. They investigate and find that in the App Router, styles must be collected during the server render and injected into the HTML head using a specific registry pattern. They create a registry.tsx file with "use client" that uses styled-components' StyleSheetManager and the useServerInsertedHTML hook from next/navigation to capture the styles during SSR and inject them into the document. They wrap their root layout with this registry, which ensures the server-generated CSS is included in the initial HTML payload, eliminating the hydration mismatch and FOUC.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T13:51:52.265528+00:00— report_created — created