From bcd9bc1e584df4cf5d5c5c0d5d7476d8a9b4122b Mon Sep 17 00:00:00 2001 From: Bunmi Oye Date: Tue, 11 Jun 2024 21:05:46 +0100 Subject: [PATCH 1/2] docs: add section for FOUC bug in next js --- pages/docs.json | 3 ++ pages/docs/faqs.mdx | 2 + sections/faqs/nextjs-13-issues.mdx | 73 ++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 sections/faqs/nextjs-13-issues.mdx diff --git a/pages/docs.json b/pages/docs.json index c6ee1464..3ae2a735 100644 --- a/pages/docs.json +++ b/pages/docs.json @@ -173,6 +173,9 @@ { "title": "How do I use styled-components with create-react-app?" }, + { + "title": "Why do I see a flash of unstyled content (FOUC) in my Next.js 13 app?" + }, { "title": "How can I fix issues when using npm link or yarn link?" }, diff --git a/pages/docs/faqs.mdx b/pages/docs/faqs.mdx index ea17e1aa..1f762456 100644 --- a/pages/docs/faqs.mdx +++ b/pages/docs/faqs.mdx @@ -13,6 +13,7 @@ import MigrationV4 from '../../sections/faqs/migration-v4.mdx' import MigrationV5 from '../../sections/faqs/migration-v5.mdx' import MigrationV6 from '../../sections/faqs/migration-v6.mdx' import CRA from '../../sections/faqs/create-react-app.mdx' +import NextJs13 from '../../sections/faqs/nextjs-13-issues.mdx' import NPMLink from '../../sections/faqs/npm-link.mdx' import FlickeringText from '../../sections/faqs/flickering-text.mdx' import DeclareComponentsInRenderMethod from '../../sections/faqs/declare-components-in-render-method.mdx' @@ -39,6 +40,7 @@ export default ({ children }) => ( + diff --git a/sections/faqs/nextjs-13-issues.mdx b/sections/faqs/nextjs-13-issues.mdx new file mode 100644 index 00000000..c4adc830 --- /dev/null +++ b/sections/faqs/nextjs-13-issues.mdx @@ -0,0 +1,73 @@ +## Why do I see a flash of unstyled content (FOUC) in my Next.js 13 app? + +When using Next.js 13 with styled-components, 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} + + + + ) +}; +``` \ No newline at end of file From 45abf21ced116309617876a280fb462ec0c1b7e7 Mon Sep 17 00:00:00 2001 From: Bunmi Oye Date: Thu, 4 Jul 2024 17:11:38 +0100 Subject: [PATCH 2/2] MOVE: FOUC fix notes to SSR section --- pages/docs.json | 3 - pages/docs/faqs.mdx | 2 - sections/advanced/server-side-rendering.mdx | 74 +++++++++++++++++++++ sections/faqs/nextjs-13-issues.mdx | 73 -------------------- 4 files changed, 74 insertions(+), 78 deletions(-) delete mode 100644 sections/faqs/nextjs-13-issues.mdx diff --git a/pages/docs.json b/pages/docs.json index 3ae2a735..c6ee1464 100644 --- a/pages/docs.json +++ b/pages/docs.json @@ -173,9 +173,6 @@ { "title": "How do I use styled-components with create-react-app?" }, - { - "title": "Why do I see a flash of unstyled content (FOUC) in my Next.js 13 app?" - }, { "title": "How can I fix issues when using npm link or yarn link?" }, diff --git a/pages/docs/faqs.mdx b/pages/docs/faqs.mdx index 1f762456..ea17e1aa 100644 --- a/pages/docs/faqs.mdx +++ b/pages/docs/faqs.mdx @@ -13,7 +13,6 @@ import MigrationV4 from '../../sections/faqs/migration-v4.mdx' import MigrationV5 from '../../sections/faqs/migration-v5.mdx' import MigrationV6 from '../../sections/faqs/migration-v6.mdx' import CRA from '../../sections/faqs/create-react-app.mdx' -import NextJs13 from '../../sections/faqs/nextjs-13-issues.mdx' import NPMLink from '../../sections/faqs/npm-link.mdx' import FlickeringText from '../../sections/faqs/flickering-text.mdx' import DeclareComponentsInRenderMethod from '../../sections/faqs/declare-components-in-render-method.mdx' @@ -40,7 +39,6 @@ export default ({ children }) => ( - 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. diff --git a/sections/faqs/nextjs-13-issues.mdx b/sections/faqs/nextjs-13-issues.mdx deleted file mode 100644 index c4adc830..00000000 --- a/sections/faqs/nextjs-13-issues.mdx +++ /dev/null @@ -1,73 +0,0 @@ -## Why do I see a flash of unstyled content (FOUC) in my Next.js 13 app? - -When using Next.js 13 with styled-components, 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} - - - - ) -}; -``` \ No newline at end of file