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

styled-components are not working with Next.js SSR #3634

Closed
dhavalveera opened this issue Nov 29, 2021 · 14 comments
Closed

styled-components are not working with Next.js SSR #3634

dhavalveera opened this issue Nov 29, 2021 · 14 comments

Comments

@dhavalveera
Copy link

Hello,

I've recently come to know about the babel-plugin-styled-components and added the following code snippet into .babelrc.

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "ssr": false
      }
    ]
  ]
}

but when I explicitly refresh my browser, the styled components are not working as defined. like styled-components don't get loaded as required.

I tried to change the "ssr": true as well but not working.

please anyone can help me to solve the issue I am facing?

@matthiaaas
Copy link

Did you update your _document.js file accordingly? You will need to create a stylesheet server-side.

Check out this example of an _document.js.

@dhavalveera
Copy link
Author

Did you update your _document.js file accordingly? You will need to create a stylesheet server-side.

Check out this example of an _document.js.

it's quite compulsory to declare the above code in _document.tsx? @matthiaaas

@matthiaaas
Copy link

@dhavalveera It's required. Just add it to your document.js/document.tsx, restart your dev server and everything will work fine.

@AElmoznino
Copy link

@dhavalveera I believe it should be:

{
  "presets": ["next/babel"],
  "plugins": [["styled-components", { "ssr": true }]]
}

(notice it's just styled-components instead of babel-plugin-styled-components). Also remember to npm install babel-plugin-styled-components). At least it's like so in the project I just took over and it works fine 😄

@dhavalveera
Copy link
Author

@dhavalveera It's required. Just add it to your document.js/document.tsx, restart your dev server and everything will work fine.

if I put the above-shared code in _document.js/_document.tsx then where to put Meta Tags and others codes in it? like Head, body, Main, NextScript?

@agriffis
Copy link
Contributor

agriffis commented Jan 6, 2022

@dhavalveera You can put them in the same file. Here's an example: https://github.com/agriffis/agcom/blob/4783dcb9eeae67de8765a551f4336e7068eed335/pages/_document.tsx

Be aware that this is probably not the source of the problem you're experiencing. Rendering styles in SSR is an optimization, not a requirement. When you say:

the styled components are not working as defined. like styled-components don't get loaded as required.

That means that you have some other issues in your code that are probably not going to be solved by enabling SSR rendering of styles.

@kitten kitten closed this as completed Jan 6, 2022
@kitten
Copy link
Member

kitten commented Jan 6, 2022

Duplicate of #3634

@dhavalveera Please don't open duplicates across repos

@ola-dola
Copy link

For newcomers to this issue, or if your app is running the new SWC compiler(default from v12), simply add the following to next.config.js:

compiler: {
    styledComponents: true,
  }

https://nextjs.org/docs/advanced-features/compiler#styled-components

@LOGANLEEE
Copy link

For newcomers to this issue, or if your app is running the new SWC compiler(default from v12), simply add the following to next.config.js:

compiler: {
    styledComponents: true,
  }

https://nextjs.org/docs/advanced-features/compiler#styled-components

for some reason even tho I added it still having same issue.. :(

@SantiiRepair
Copy link

solved? im having the same issue

@SantiiRepair
Copy link

module.exports = { compiler: { // Enables the styled-components SWC transform styledComponents: true, reactStrictMode: true, } }

solved for me!

@say8425
Copy link

say8425 commented Mar 17, 2023

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  compiler: {
    reactStrictMode: true,
    styledComponents: true,
  },
};

module.exports = nextConfig;

Add styledComponents and reactStrictMode into the compiler on the next.config.js.

@lucasmelz
Copy link

Actually, I've looked into this issue and my conclusion is that there is not really a way to make styled-components to be rendered on the server side, at least not with Next.js 13 and app router... But it is possible to make styled-components work with Next.js 13 without any "delay bugs" using client-side rendering and a few workarounds.

Step 1: add the following to your next.config.js file

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  compiler: {
    styledComponents: true,
  },
}

module.exports = nextConfig

Step 2: create the registry.tsx file with the following code:

'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>
  )
}

Step 3: add the 'use client' directive to your layout.tsx file and wrap all the children components on your layout with the StyledComponentsRegistry component.

I've made a tutorial if anyone needs further help:
https://www.youtube.com/watch?v=3tgrPm2aKog

@mil0serdnaya
Copy link

mil0serdnaya commented Oct 12, 2023

Thank you! You saved me from mental breakdown :)

Actually, I've looked into this issue and my conclusion is that there is not really a way to make styled-components to be rendered on the server side, at least not with Next.js 13 and app router... But it is possible to make styled-components work with Next.js 13 without any "delay bugs" using client-side rendering and a few workarounds.

Step 1: add the following to your next.config.js file

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  compiler: {
    styledComponents: true,
  },
}

module.exports = nextConfig

Step 2: create the registry.tsx file with the following code:

'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>
  )
}

Step 3: add the 'use client' directive to your layout.tsx file and wrap all the children components on your layout with the StyledComponentsRegistry component.

I've made a tutorial if anyone needs further help: https://www.youtube.com/watch?v=3tgrPm2aKog

Thank you! You saved me from a mental breakdown :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests