6

I am new to NextJS, I need to change the CSS class prefix + suffix to this format:

<li class="desktop__menu-item--2feEH"></li>
<li class="desktop__menu-item--2feEH"></li>
<li class="desktop__menu-item--2feEH"></li>
<li class="desktop__menu-item--2feEH"></li>

How to change the component.module.css CSS classes to the format of [path][name]__[local]--[hash:base64:5], can someone explain it to me please?

Do I need a config.js file? I am using Next.js v10.0.9

2 Answers 2

3

for Next.js with version >= 12

the accepted answer only works for Next.js with version < 12.

const loaderUtils = require('loader-utils')

const regexEqual = (x, y) => {
  return (
  x instanceof RegExp &&
  y instanceof RegExp &&
  x.source === y.source &&
  x.global === y.global &&
  x.ignoreCase === y.ignoreCase &&
  x.multiline === y.multiline
  )
}

/**
 * Generate context-aware class names when developing locally
 */
const localIdent = (loaderContext, localIdentName, localName, options) => {
  return (
    loaderUtils
      .interpolateName(loaderContext, btoa(unescape(encodeURIComponent(localName))), options)
      // Webpack name interpolation returns `about_about.module__root` for
      // `.root {}` inside a file named `about/about.module.css`. Let's simplify
      // this.
      .replace(/\.module_/, '_')
      // Replace invalid symbols with underscores instead of escaping
      // https://mathiasbynens.be/notes/css-escapes#identifiers-strings
      .replace(/[^a-zA-Z0-9-_]/g, '_')
      // "they cannot start with a digit, two hyphens, or a hyphen followed by a digit [sic]"
      // https://www.w3.org/TR/CSS21/syndata.html#characters
      .replace(/^(\d|--|-\d)/, '__$1')
  )
}

function cssLoaderOptions(modules) {
  const { getLocalIdent, ...others } = modules // Need to delete getLocalIdent else localIdentName doesn't work
  return {
    ...others,
    getLocalIdent: localIdent,
    mode: 'local',
  }
}

const path = require('path')
module.exports = {
  webpack: config => {
    config.resolve.modules.push(path.resolve('./'))
    const oneOf = config.module.rules.find((rule) => typeof rule.oneOf === 'object')
   
    if (oneOf) {
      // Find the module which targets *.scss|*.sass files
      const moduleSassRule = oneOf.oneOf.find(
        (rule) => regexEqual(rule.test, /\.module\.(scss|sass)$/) //highlight-line
      )
      
      if (moduleSassRule) {
        // Get the config object for css-loader plugin
        const cssLoader = moduleSassRule.use.find(
          ({ loader }) => loader.includes('css-loader') //highlight-line
        )
        console.log(cssLoader,"cssloader")
        if (cssLoader) {
          cssLoader.options = {
            ...cssLoader.options,
            modules: cssLoaderOptions(cssLoader.options.modules), //highlight-line
           
          }
        }
      }
    }

  return config

  },

  eslint: {
    // Warning: This allows production builds to successfully complete even if
    // your project has ESLint errors.
    ignoreDuringBuilds: true,
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

Next.js doesn't yet provide a built-in way to modify the css-loader options.

However, you can still do so by customising the webpack configuration in your next.config.js. You'll need to manually go through each css-loader module loader and add the desired localIdentName.

// next.config.js

module.exports = {
    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'
                ) {
                    delete moduleLoader.options.modules.getLocalIdent;
                    moduleLoader.options = {
                        ...moduleLoader.options,
                        modules: {
                            ...moduleLoader.options.modules,
                            localIdentName: '[path][name]__[local]--[hash:base64:5]'
                            // You can also add other css-loader options here
                        }
                    };
                }
            });
        });

        return config;
    }
};

1 Comment

I got a arror: TypeError: getLocalIdent is not a function

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.