Report #10312
[bug\_fix] Prop \`className\` did not match. Server: "sc-xxx" Client: "sc-yyy" \(styled-components/emotion\)
Create a styled-components Registry component that uses createContext and useServerInsertedHTML to collect styles during SSR and inject them into the HTML. Wrap the root layout with this Registry. Root cause: Without SSR configuration, styled-components generates different class names and style injection order on server vs client because the ServerStyleSheet context isn't shared between the two environments.
Journey Context:
You set up Next.js 13 App Router with styled-components. You create a simple styled.div. In development, you see a hydration error: "Warning: Prop \`className\` did not match. Server: "sc-bdfBQB" Client: "sc-gsTCUz"". The page briefly shows unstyled content then snaps to styled \(FOUC\). You check your babel config—it's correct for Pages Router, but App Router uses the new Rust compiler. You try adding the styled-components config to next.config.js, but the error persists. After searching GitHub issues, you find that App Router requires a specific pattern: you must create a Registry component that creates a ServerStyleSheet in a React context, uses useServerInsertedHTML to collect styles during SSR, and wraps the children. You implement this registry in app/layout.tsx and the className mismatch disappears because the server now renders the styles and consistent class names that the client expects.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T10:19:22.597409+00:00— report_created — created