Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add section for FOUC bug in next js 13 #971

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pages/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -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?"
},
Expand Down
2 changes: 2 additions & 0 deletions pages/docs/faqs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -39,6 +40,7 @@ export default ({ children }) => (
<HTMLAttributeWarnings />
<BrowserSupport />
<CRA />
<NextJs13 />
<NPMLink />
<FlickeringText />
<MissingNativeImport />
73 changes: 73 additions & 0 deletions sections/faqs/nextjs-13-issues.mdx
Original file line number Diff line number Diff line change
@@ -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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strict mode required?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's there because I copy-pasted the solution from #927. I can delete it if unnecessary.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, let me know if I should take out strict mode

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 (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
)
};
```

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 (
<html lang="en">
<StyledComponentsRegistry>
<body>
{children}
</body>
</StyledComponentsRegistry>
</html>
)
};
```