How to configure Next.js with Antd / Less and Sass / CSS modules

Edit: This answer is definitely outdated for current versions of next.js, check the other answers below.

After multiple hours of research I found now finally the right solution and wanted to share it:

.babelrc (no magic here)

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "import",
      {
        "libraryName": "antd",
        "style": true
      }
    ]
  ]
}

next.config.js:

/* eslint-disable */
const withLess = require('@zeit/next-less');
const withSass = require('@zeit/next-sass');
const lessToJS = require('less-vars-to-js');
const fs = require('fs');
const path = require('path');

// Where your antd-custom.less file lives
const themeVariables = lessToJS(
  fs.readFileSync(path.resolve(__dirname, './assets/antd-custom.less'), 'utf8')
);

module.exports = withSass({
  cssModules: true,
  ...withLess({
    lessLoaderOptions: {
      javascriptEnabled: true,
      modifyVars: themeVariables, // make your antd custom effective
      importLoaders: 0
    },
    cssLoaderOptions: {
      importLoaders: 3,
      localIdentName: '[local]___[hash:base64:5]'
    },
    webpack: (config, { isServer }) => {
      //Make Ant styles work with less
      if (isServer) {
        const antStyles = /antd\/.*?\/style.*?/;
        const origExternals = [...config.externals];
        config.externals = [
          (context, request, callback) => {
            if (request.match(antStyles)) return callback();
            if (typeof origExternals[0] === 'function') {
              origExternals[0](context, request, callback);
            } else {
              callback();
            }
          },
          ...(typeof origExternals[0] === 'function' ? [] : origExternals)
        ];

        config.module.rules.unshift({
          test: antStyles,
          use: 'null-loader'
        });
      }
      return config;
    }
  })
});

The final hint how to write the withSass withLess use and to put the cssModules: true in the outer object came from this comment here.

While I was already trying different combinations derived from the examples before:
next+ant+less
next+sass

For completion here the dependencies in my package.json:

...
"dependencies": {
    "@zeit/next-less": "^1.0.1",
    "@zeit/next-sass": "^1.0.1",
    "antd": "^4.1.3",
    "babel-plugin-import": "^1.13.0",
    "less": "^3.11.1",
    "less-vars-to-js": "^1.3.0",
    "next": "^9.3.4",
    "node-sass": "^4.13.1",
    "null-loader": "^3.0.0",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "sass": "^1.26.3"
  }
...

I hope this helps other people to find this solution faster. 🙂

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)