I'm using CSS modules (.scss
) with Next.js and have a kebab naming-convention. In other words, something like this:
.member-btn {
background: #fff;
}
The problem that I'm facing is that in order to use this with className
I have to do it like styles["member-btn"]
. E.g.
<Button className={styles["member-btn"]}>
Hello world
</Button>
However, I would like to use it with styles.memberBtn
and use it like an object (IDE also provides built-in support for this). E.g.
<Button className={styles.memberBtn}>Hello world</Button>
Is this possible in Next.js?
Next.js doesn't provide an easy, built-in way to customise CSS Modules options yet (see related RFC vercel/next.js#15818). This means you have to dig into webpack and customise the css-loader
used by Next.js directly in your next.config.js
.
Here's a potential solution that works for the latest Next.js versions, based off the answers in vercel/next.js#11267.
// next.config.js
module.exports = {
// other existing configurations here...
webpack: (config) => {
const rules = config.module.rules
.find((rule) => typeof rule.oneOf === 'object').oneOf.filter((rule) => Array.isArray(rule.use));
rules.forEach((rule) => {
rule.use.forEach((moduleLoader) => {
if (
moduleLoader.loader !== undefined
&& moduleLoader.loader.includes('css-loader')
&& typeof moduleLoader.options.modules === 'object'
) {
moduleLoader.options = {
...moduleLoader.options,
modules: {
...moduleLoader.options.modules,
// This is where we allow camelCase class names
exportLocalsConvention: 'camelCase'
}
};
}
});
});
return config;
}
}
The idea is to target the css-loader
used internally by Next.js and overwrite the exportLocalsConvention
option to 'camelCase'
. This enables the usage of camelCased class names, e.g. styles.memberBtn
.