next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Dynamic styles don't work with styled components and next13 app/layout

Open hugomendonca98 opened this issue 2 years ago • 1 comments

Verify canary release

  • [X] I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System: Platform: linux Arch: x64 Version: #58-Ubuntu SMP Thu Oct 13 08:03:55 UTC 2022 Binaries: Node: 16.13.2 npm: 8.1.2 Yarn: 1.22.19 pnpm: 6.11.0 Relevant packages: next: 13.0.2 eslint-config-next: 13.0.0 react: 18.2.0 react-dom: 18.2.0

What browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

Describe the Bug

When trying to use dynamic styles through props and styled components the styles that were supposed to be applied don't work.

Expected Behavior

You would expect styles to be applied when passing props change.

Link to reproduction

https://github.com/hugomendonca98/Next13-bug

To Reproduce

Error on run yarn build: image

yarn dev it just removes all styles from the component that was supposed to apply the new style.

hugomendonca98 avatar Nov 06 '22 02:11 hugomendonca98

Also noticed this behaviour. Styles just not getting applied.

Screenshot 2022-11-09 at 08 07 29

This is after following the guide for styled components

simonpkerr avatar Nov 09 '22 08:11 simonpkerr

@hugomendonca98 we updated the styled components guide few days ago, in your reproduction you need to update the style registry

- styledComponentsStyleSheet.seal();
+ // @ts-ignore
+ styledComponentsStyleSheet.instance.clearTag();

I added the @ts-ignore here since clearTag() is not exposed on API typing so far. This should resolve your issue.

@simonpkerr not sure if you're using the above setup, would you mind trying that out, if that not working can you provide a reproduction for your case? Thanks

huozhi avatar Nov 22 '22 11:11 huozhi

Also noticed this behaviour. Styles just not getting applied.

Screenshot 2022-11-09 at 08 07 29

This is after following the guide for styled components

Same problem I've noticed as well.

abhilashlr7 avatar Nov 23 '22 03:11 abhilashlr7

@abhilashlr7 can you provide a minimal reproduction for it?

huozhi avatar Nov 23 '22 11:11 huozhi

@abhilashlr7 can you provide a minimal reproduction for it?

Sure will try my best to share it asap. But I can tell you the base of the app I was working this with:

NextJs: 13+ Antd: 5+ Styled-components: 6-beta+

Followed the exact same details as mentioned in the beta website of nextjs mentioned under CSS-in-JS section of styled components. The ant styles loaded perfectly in the html, but the component styles didn't.

I will try to send a reproduction of it asap

abhilashlr7 avatar Nov 23 '22 11:11 abhilashlr7

It absolutely does not work as defined. I can make it work using some crazy voodoo but i don't even know what the params are that caused it.

Just copy and paste your own example - it doesn't work :-P The classnames are all defined but no stylesheets are generated.

bradennapier avatar Nov 27 '22 06:11 bradennapier

@hugomendonca98 we updated the styled components guide few days ago, in your reproduction you need to update the style registry

- styledComponentsStyleSheet.seal();
+ // @ts-ignore
+ styledComponentsStyleSheet.instance.clearTag();

I added the @ts-ignore here since clearTag() is not exposed on API typing so far. This should resolve your issue.

@simonpkerr not sure if you're using the above setup, would you mind trying that out, if that not working can you provide a reproduction for your case? Thanks

Same issue here, this solution does not work.

johnkm516 avatar Dec 01 '22 05:12 johnkm516

Having the same issue. I can also try to provide a minimal reproduction. Modifying a used style has the same effect (hot reload), removes all styles (applies the classname, but never regenerates the stylesheet). this is also the case when attempting to use styled component themes.

edit @huozhi: https://github.com/russbot/next13-styled-components

russbot avatar Dec 05 '22 17:12 russbot

After googling few hours I found the solution on this blog Post

this fixed the issue for me:

  1. First create a new 'pages/_document.js' file
  2. Second add this in your 'pages/_document.js' file :
import Document, { Head, Html, Main, NextScript } from 'next/document'
    import { ServerStyleSheet } from 'styled-components'

    export default class MyDocument extends Document {
      render() {
        return (
          <Html lang="en">
            <Head></Head>
            <body>
              <Main />
              <NextScript />
            </body>
          </Html>
        )
      }

      static async getInitialProps(ctx) {
        const sheet = new ServerStyleSheet()
        const originalRenderPage = ctx.renderPage

        try {
          ctx.renderPage = () =>
            originalRenderPage({
              enhanceApp: (App) => (props) =>
                sheet.collectStyles(<App {...props} />),
            })

          const initialProps = await Document.getInitialProps(ctx)
          return {
            ...initialProps,
            styles: (
              <>
                {initialProps.styles}
                {sheet.getStyleElement()}
              </>
            ),
          }
        } finally {
          sheet.seal()
        }
      }
    }

franckadil avatar Dec 07 '22 00:12 franckadil

@franckadil i see a "first", is there a second? lol

Thanks for the feedback, I have edited the answer to be more precise. I hope you will find this answer helpful.

franckadil avatar Dec 07 '22 00:12 franckadil

@franckadil

You're using the old pages directory. This issue is specifically referring to the new app directory in Next13. To everyone using the new app directory and trying to get this to work, I found a temporary solution that at least actually works . This uses emotion cache.

  1. Delete lib/styled-components.tsx.
  2. Replace app/RootStyleRegistry.tsx with this :
'use client';

import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import { useServerInsertedHTML } from 'next/navigation';
import { useState } from 'react';

export default function RootStyleRegistry({
  children,
}: {
  children: React.ReactNode;
}) {
  const [cache] = useState(() => {
    const cache = createCache({ key: 'css' });
    cache.compat = true;
    return cache;
  });

  useServerInsertedHTML(() => {
    return (
      <style
        data-emotion={`${cache.key} ${Object.keys(cache.inserted).join(' ')}`}
        dangerouslySetInnerHTML={{
          __html: Object.values(cache.inserted).join(' '),
        }}
      />
    );
  });

  return <CacheProvider value={cache}>{children}</CacheProvider>;
}

johnkm516 avatar Dec 07 '22 00:12 johnkm516

Hi y'all, I found a workaorund for that is: not rendering StyleSheetManager in browser and directly render the children for the StyledComponentsRegistry.

function StyledComponentsRegistry({ children })  {
+    if (typeof window !== 'undefined') {
+      return children
+    }
    return (
      <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
        {children as React.ReactElement}
      </StyleSheetManager>
    )
}

I tried few reproduction it seems working. Can someone else confirm if that works for them? Thanks

huozhi avatar Dec 08 '22 19:12 huozhi

Hi y'all, I found a workaorund for that is: not rendering StyleSheetManager in browser and directly render the children for the StyledComponentsRegistry.

function StyledComponentsRegistry({ children })  {
+    if (typeof window !== 'undefined') {
+      return children
+    }
    return (
      <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
        {children as React.ReactElement}
      </StyleSheetManager>
    )
}

I tried few reproduction it seems working. Can someone else confirm if that works for them? Thanks

Can confirm this works for me! I had a component rendering a bit later (after a fetch), which previously didn't have it's styles getting applied. It's all working now! Thanks!

nordowl avatar Dec 08 '22 20:12 nordowl

Hi y'all, I found a workaorund for that is: not rendering StyleSheetManager in browser and directly render the children for the StyledComponentsRegistry.

function StyledComponentsRegistry({ children })  {
+    if (typeof window !== 'undefined') {
+      return children
+    }
    return (
      <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
        {children as React.ReactElement}
      </StyleSheetManager>
    )
}

I tried few reproduction it seems working. Can someone else confirm if that works for them? Thanks

It's working for me as well

russbot avatar Dec 08 '22 20:12 russbot

We have update it to the docs for css-in-js styled-componets section. Thanks y'all for reporting! 🙏

huozhi avatar Dec 12 '22 15:12 huozhi

@hugomendonca98несколько дней назад мы обновили руководство по компонентам стилей, в вашем воспроизведении вам необходимо обновить реестр стилей.

- styledComponentsStyleSheet.seal();
+ // @ts-ignore
+ styledComponentsStyleSheet.instance.clearTag();

Я добавил @ts-ignoreсюда, так как clearTag()до сих пор не подвергался вводу API. Это должно решить вашу проблему.

@simonpkerrне уверен, используете ли вы описанную выше настройку, не могли бы вы попробовать это, если это не работает, можете ли вы предоставить репродукцию для вашего случая? Спасибо

this is works for me, thanks!

chillside avatar Dec 23 '22 00:12 chillside

Thanks for the workaround @huozhi! To me the warning at the top of the CSS-in-JS page makes the workaround a bit ambiguous ("CSS-in-JS libraries which require runtime JavaScript are not currently supported..."). To me it implies that styled components won't work and that's what I thought initially until I found this issue. Is it correct to say that with that workaround that styled components will work as expected with Next.js 13 and server components, or are there any caveats we need to be aware of (aside from that the whole thing is still beta)?

gpoole avatar Jan 04 '23 00:01 gpoole

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

github-actions[bot] avatar Feb 03 '23 12:02 github-actions[bot]