When the generateClassName
is used, it is not applied to the server rendered style sheets. It is only applied for the client side.
The class names are changed according to the generateClassName
for both server side and client side.
Codesandbox: https://codesandbox.io/embed/github/kamalarieff/nextjs-mui-cls/tree/master/
Repo: https://github.com/kamalarieff/nextjs-mui-cls.git
I've added the StylesProvider as such. However, when I view the page source, I can't find my new class prefix anywhere:
But when I do inspect element, I can find it:
It seems like class name generator is applied to client side only.
My suspicion is that the instance of the class name generator is not the same for SSR and CSR but I don't know how to confirm this.
Solutions I've tried:
NODE_ENV=production
to both the build and start step according to this issuejs
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: App => props => sheets.collect(<App {...props} />),
});
pages/_document.js
. This worked but there was a flash of unstyled content. There's also no documentation regarding enhanceApp
so I wasn't sure about this implementation.seed
property works but there was also a flash of unstyled content.We have a separate package that provides react components and they are built with material ui. When I import this component into our app, their class names are conflicting with each other.
This repo was cloned from https://github.com/mui-org/material-ui/tree/master/examples/nextjs.
Dependencies:
"@material-ui/core": "latest",
"@material-ui/styles": "latest",
"clsx": "latest",
"next": "latest",
"prop-types": "latest",
"react": "latest",
"react-dom": "latest"
๐
You also need to apply the custom generator on the server-side:
_document.js
const generateClassName = createGenerateClassName({
productionPrefix: "yoghirt"
});
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets({
serverGenerateClassName: generateClassName
});
@oliviertassinari Awesome now it works. But I have a different issue now. After the app has been mounted, the server side style sheets are removed. But this only happens in my project though not the example project. Could one of the node_modules be affecting this?
@kamalarieff The server-side styles are meant to be removed, so the client can inject them back.
@oliviertassinari I see. So does that mean the client is injecting partially empty styles?
I found the issue. The styles disappear when I connect the application to redux.
I'm able to replicate the issue here.
I've found the solution. For anyone reading, here it is.
Here's the repo for good measure.
@oliviertassinari the
serverGenerateClassName
was not mentioned in the docs. Might be a good idea to include them for future devs.
@oliviertassinari Thanks, I really think the serverGenerateClassName
needs to be documented. I spent an hour looking for this. The docs suggest that options should be sent like for StylesProvider
. Thank you for the lib by the way :)
serverGenerateClassName
Should add it to the document ๐
๐คฃ really should add it to the document, wasted another 10 minutes today
Important thing is that don't use the same instance of generateClassName
on client and server
const classPrefix = "my-prefix";
const generateClassName = createGenerateClassName({
seed: classPrefix,
});
...
<StylesProvider generateClassName={generateClassName}>..</StylesProvider>
// on server
new ServerStyleSheets({
serverGenerateClassName: generateClassName,
});
const classPrefix = "my-prefix";
const generateClassName = () => createGenerateClassName({
seed: classPrefix,
});
...
<StylesProvider generateClassName={generateClassName()}>..</StylesProvider>
// on server
new ServerStyleSheets({
serverGenerateClassName: generateClassName(),
});
More here
Most helpful comment
You also need to apply the custom generator on the server-side:
_document.js