next.js
next.js copied to clipboard
Dynamic styles don't work with styled components and next13 app/layout
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:
yarn dev it just removes all styles from the component that was supposed to apply the new style.
Also noticed this behaviour. Styles just not getting applied.
This is after following the guide for styled components
@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
Also noticed this behaviour. Styles just not getting applied.
This is after following the guide for styled components
Same problem I've noticed as well.
@abhilashlr7 can you provide a minimal reproduction for it?
@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
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.
@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 sinceclearTag()
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.
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
After googling few hours I found the solution on this blog Post
this fixed the issue for me:
- First create a new 'pages/_document.js' file
- 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 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
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.
- Delete lib/styled-components.tsx.
- 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>;
}
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
Hi y'all, I found a workaorund for that is: not rendering
StyleSheetManager
in browser and directly render thechildren
for theStyledComponentsRegistry
.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!
Hi y'all, I found a workaorund for that is: not rendering
StyleSheetManager
in browser and directly render thechildren
for theStyledComponentsRegistry
.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
We have update it to the docs for css-in-js styled-componets section. Thanks y'all for reporting! 🙏
@hugomendonca98несколько дней назад мы обновили руководство по компонентам стилей, в вашем воспроизведении вам необходимо обновить реестр стилей.
- styledComponentsStyleSheet.seal(); + // @ts-ignore + styledComponentsStyleSheet.instance.clearTag();
Я добавил
@ts-ignore
сюда, так какclearTag()
до сих пор не подвергался вводу API. Это должно решить вашу проблему.@simonpkerrне уверен, используете ли вы описанную выше настройку, не могли бы вы попробовать это, если это не работает, можете ли вы предоставить репродукцию для вашего случая? Спасибо
this is works for me, thanks!
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)?
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.