CSS classname from component library rewritten

75 views Asked by At

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 .

1

There are 1 answers

0
Jbrcz On

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 with rollup-plugin-banner2 package:

banner((chunck) => {
    if(!bannedUseClientFiles.includes(chunck.fileName)){
      return "'use client';\n";
    }
    return undefined
  })