Open ajayjaggi97 opened 2 years ago
@ajayjaggi97 I've tried for the last 3 days to get it to work with next.js and I'm finally happy to use it. First of all: I want to use it for a component-library and not directly in next.js. I think for direct usage, next.js already has a nice system through the *.module.scss/css-files.
This is where the magic happens: Here is the content of my _app.tsx:
export default function MyApp({ }: AppProps) {
const styles: string[] = useMemo(() => [], []);
const addStyles = useCallback(
(...newStyles) => {
if (typeof document === 'undefined') {
styles.push(...newStyles.map((s) => s._getCss()));
} else {
newStyles.forEach((s) => s._insertCss());
}
},
[styles]
);
return (
<>
<StyleProvider value={{ insertCss: addStyles }}>
<ColorInput />
</StyleProvider>
<StyleRenderer styles={styles} />
</>
);
}
and my StyleRenderer.tsx:
export type StyleRendererProps = { styles: string[] };
export function StyleRenderer({ styles }: StyleRendererProps) {
return (
<Head>
<style>{styles.join()}</style>
</Head>
);
}
Note that I use useMemo
in order to save the styles and StyleRenderer, which only displays the styles. This is because of how nextjs works. Once the rendermethod is done, you can't trigger an rerender on the server, regardless what you do (or at least I could not trigger one). But subcomponents are still rendering. Since the components are called top-down, the ColorInput
is called before the StyleRenderer
. Inside the ColorInput
I use the useStyles
hook, which calls addStyles
from _app.tsx
. Since I used useMemo
for styles, it is the same instance inside addStyles
as is passed to StyleRenderer
,
Since StyleRenderer
renders last, it will render all the styles needed inside the server rendering.
On the client, I just use the s._insertCss()
method without any problems.
And also note that I did not use StyleContext.Provider
but StyleProvier
which is an reexport of StyleContext.Provider
from my component-library. This is needed or else the context used from useStyles
inside the library is a different one than the one provides through StyleContext.Provider
inside next.js
Hey @Ainias .Thanks for the solution. I had the similar use case where we had a components library.
Do you have a specific example for reference? thank you
@Ainias @ajayjaggi97 can you give a example? I'm very curious about how to actually implement this🤪.
Can you pls share the insights of using isomorphic-style-loader with next.js. How can we pass the required context value of insertCss??