Report #66260
[bug\_fix] Hydration failed because the initial UI does not match \(Styled Components/Emotion FOUC\)
Implement a Registry pattern: Create a registry.tsx that uses React.useServerInsertedHTML to collect styles during SSR and inject them into the . Wrap the root layout children with this Registry. For styled-components specifically, use StyleSheetManager with disableCSSOMInjection during build.
Journey Context:
Developer is migrating a large e-commerce site from Next.js Pages Router to App Router. They use styled-components extensively. After migration, the site works in dev mode \(npm run dev\), but on production build \(npm run build && npm start\), users see a flash of unstyled content \(FOUC\) - raw HTML with no CSS for a split second, then styles apply. The console shows hydration mismatch warnings: className did not match. Developer inspects the server-rendered HTML and sees styled-component class names like "sc-bdVaJa" but the style tags are missing from the . They realize that in Pages Router, they had a custom \_document.tsx that used ServerStyleSheet to extract styles. In App Router, \_document.tsx doesn't exist. They search Next.js docs for "styled-components app router" and find the official example. It shows a registry.tsx file that creates a styled-components StyleSheetManager and uses the new React hook useServerInsertedHTML to collect all styles generated during the render and insert them into the DOM. They implement this registry, wrap their root layout with it, and the FOUC disappears. The hydration mismatch is resolved because the server now sends the CSS in the initial HTML.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T17:41:40.059813+00:00— report_created — created