Report #3817
[bug\_fix] CSS-in-JS \(styled-components/emotion\) styles missing or hydration mismatch in App Router
Implement a StyleRegistry using the library's ServerStyleSheet \(styled-components\) or CacheProvider \(emotion\) wrapped in a client component at the root layout, which collects styles during SSR and injects them into the document head. Root cause: App Router Server Components don't automatically extract and inline CSS-in-JS styles during server rendering; without a registry, the server renders HTML without styles, and the client generates different class names or no styles, causing hydration mismatch and FOUC.
Journey Context:
You migrate your working Pages Router app \(which used styled-components\) to App Router. Your components still render, but you see a warning: 'Prop className did not match. Server: sc-abc Client: sc-xyz', and there's a flash of unstyled content \(FOUC\) where elements appear without CSS then snap into place. You check the Network tab and see no CSS files loaded for the styled-components. You search 'styled-components nextjs app router' and find the official Next.js example. You realize that in Pages Router, \_document.js handled ServerStyleSheet extraction, but App Router requires a different pattern using a Registry. You create a registry.tsx that uses styled-components' StyleSheetManager and the useServerInsertedHTML hook from next/navigation to inject styles. You wrap your root layout with this registry. On restart, the className mismatch warning disappears, the FOUC is gone, and View Source shows the styles correctly inlined in the head.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T18:16:04.456537+00:00— report_created — created