Closed kamalarieff closed 5 years ago
👍
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
Important thing is that don't use the same instance of
generateClassName
on client and serverwrong ❌
const classPrefix = "my-prefix"; const generateClassName = createGenerateClassName({ seed: classPrefix, }); ... <StylesProvider generateClassName={generateClassName}>..</StylesProvider> // on server new ServerStyleSheets({ serverGenerateClassName: generateClassName, });
correct ✅
const classPrefix = "my-prefix"; const generateClassName = () => createGenerateClassName({ seed: classPrefix, }); ... <StylesProvider generateClassName={generateClassName()}>..</StylesProvider> // on server new ServerStyleSheets({ serverGenerateClassName: generateClassName(), });
More here
Could you be more specific? How come you could use a SINGLE instance in both server and client? These are separate machines and hence separate instances. I think what you mean is to make sure every time the server receives a request, it creates a new generator, otherwise independent request will share the same generator, causing wrong classNames generated for any request other than the first time.
Hello @oliviertassinari,
I'm trying to add productionPrefix
(and for seed
it is working the same) to my project (already added createGenerateClassName
into the document (server) and app (client)). But I get new classes ever page reload for example "myprefix5" -> "myprefix6". Have you met this issue?
I've found the same reported issue mui-org/material-ui#17423
Hello @oliviertassinari, I'm trying to add
productionPrefix
(and forseed
it is working the same) to my project (already addedcreateGenerateClassName
into the document (server) and app (client)). But I get new classes ever page reload for example "myprefix5" -> "myprefix6". Have you met this issue?I've found the same reported issue mui-org/material-ui#17423
I've found the reason. Details here https://github.com/vercel/next.js/discussions/10898#discussioncomment-1728514
createGenerateClassName
instance should be initialized in getInitialProps
.
Not obvious way and it's not clear from docs
Current Behavior 😯
When the
generateClassName
is used, it is not applied to the server rendered style sheets. It is only applied for the client side.Expected Behavior 🤔
The class names are changed according to the
generateClassName
for both server side and client side.Steps to Reproduce 🕹
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 issuefrom
pages/_document.js
. This worked but there was a flash of unstyled content. There's also no documentation regardingenhanceApp
so I wasn't sure about this implementation.seed
property works but there was also a flash of unstyled content.Context 🔦
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.
Your Environment 🌎
This repo was cloned from https://github.com/mui-org/material-ui/tree/master/examples/nextjs.
Dependencies: