diff --git a/sections/advanced/server-side-rendering.mdx b/sections/advanced/server-side-rendering.mdx index 3f1247fd..2928f01b 100644 --- a/sections/advanced/server-side-rendering.mdx +++ b/sections/advanced/server-side-rendering.mdx @@ -88,6 +88,80 @@ On this version, you [only need to add](https://github.com/vercel/next.js/blob/c For routes defined in the `app/` directory, in Next.js v13+, you'll need to put a styled-components registry in one of your layout files, as [described in Next.js docs](https://nextjs.org/docs/app/building-your-application/styling/css-in-js#styled-components). Note that this depends on styled-components v6+. Also note that the `'use client'` directive is used - so while your page will be server-side rendered, styled-components will still appear in your client bundle. +#### Note: When using Next.js 13, you might see a flash of unstyled content (FOUC) + +You may experience a flash of unstyled content (FOUC) due to "delay bugs" in client-side rendering. This happens because styled-components' styles are not immediately applied when the page is rendered, causing unstyled elements to appear for a split second. + +To resolve this issue, follow these steps: + +1. Add the following to your next.config.js file. + +```js +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, + compiler: { + styledComponents: true, + }, +} + +module.exports = nextConfig +``` +2. Create the registry.tsx file with the following code: +```tsx +'use client' + +import React, { useState } from 'react'; +import { useServerInsertedHTML } from 'next/navigation'; +import { ServerStyleSheet, StyleSheetManager } from 'styled-components'; + +export default function StyledComponentsRegistry({ + children, +}: { + children: React.ReactNode +}) { + // Only create stylesheet once with lazy initial state + // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state + const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet()) + + useServerInsertedHTML(() => { + const styles = styledComponentsStyleSheet.getStyleElement() + styledComponentsStyleSheet.instance.clearTag() + return styles + }) + + if (typeof window !== 'undefined') return <>{children} + + return ( + + {children} + + ) +}; +``` + +3. Add the ```'use client'``` directive to your layout.tsx file and wrap all the children components on your layout with the StyledComponentsRegistry component. +```tsx +'use client' +import StyledComponentsRegistry from './registry'; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + + + {children} + + + + ) +}; +``` + ### Gatsby [Gatsby](https://www.gatsbyjs.org/) has an official plugin that enables server-side rendering for styled-components.