I built a React component library based on mantine with @rollup package. This library exports custom components that are stylized with styled-components and CSS module (.module.css) files.
All css modules are bundled in javascript and injected in the body html element: Inject css
The library is bundled in esm, cjs and umd.
The css is create with this rollup plugin: rollup-plugin-styles:
styles({
modules: true,
autoModules: true,
mode: [
"inject",
{ container: "body", singleTag: true, prepend: true, attributes: { id: "global" } },
],
})
The problem I have is that the classname I used in my component are rewritten by next.js when it's pre-processed on the server then sent to the client. Example: Here in my esm module file:
var css = ".Layout_module_container__61ae088e {\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n.Layout_module_main__61ae088e {\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n overflow-y: auto;\n padding: 0 1.5rem;\n}";
var modules_e616121b = {"container":"Layout_module_container__61ae088e","main":"Layout_module_main__61ae088e"};
n(css,{"container":"body","singleTag":true,"prepend":true,"attributes":{"id":"global"}});
Here in my js loaded stylesheet (in body html):
<body>
<style type="text/css" id="global">
@media (min-width: 36rem) {.Footer_module_container__fe0fb20d {
padding: var(--mantine-spacing-md)
}
}
@media (max-width: 36rem) {.Footer_module_container__fe0fb20d {
padding: var(--mantine-spacing-xs)
}
}
.Footer_module_infosContainer__fe0fb20d {
flex-direction: column;
flex-grow: 1;
align-items: start;
}
@media (min-width: 768px){
.Footer_module_infosContainer__fe0fb20d {
flex-direction: row;
align-items: center;
gap: 10
}
}
...
</style>
</body>
Here is the div where the name should be: div
<div style="gap:var(--mantine-spacing-md);align-items:center;justify-content:space-around" class="m-8bffd616 mantine-Flex-root __m__-R1d5bsm"/>
The classname is rewritten in the html with somethings like: __m__* but not in the stylesheet.
I also noticed that the same behaviour is happening with styled-components.
styled-component error
next-dev.js:20 Warning: Prop `className` did not match. Server: "m-8a5d1357 mantine-Title-root" Client: "WebsiteSelector_module_websiteName__547dd6e4 m-8a5d1357 mantine-Title-root"
I found some fixes on the internet but nothing worked for me. I tried:
- remove inject css in js and create separate css file. import it in App.tsx on next.js
- add babel-plugin-styled-components plugins in babel.rc file. But disabled swc to enable babel (performance loose)
My library is working perfectly with vite.js so problem is only on next.js side.
My app versions:
dependencies: {
"next": "12.3.4",
"react": "18.2.0",
"react-dom": "18.2.0",
}
My library version:
"dependencies": {
"react": "18.2.0",
"react-dom": "18.2.0",
},
"devDependencies":{
"react": "^18.2.0",
"react-dom": "^18.2.0",
"styled-components": "^6.1.8"
}
Thanks for help .
Finally found a solution.
The problem was coming from the the next.js SSR. I needed to add
"use-client;"in the top of every of my library components. I did this withrollup-plugin-banner2package: