4

I am trying to add a variable to my scss files, referenced to .env variable. To achieve this, I've read a few tutorials, and I found this. I need to add this configuration to my next.config.js

const withImages = require('next-images');

module.exports = withImages({
    webpack(config, options) {
        config.module.rules.push({
            test: /\.s[ac]ss$/i,
            use: [
                {
                    loader: "css-loader",
                    options: {
                        importLoaders: 2,
                        modules: {
                            compileType: 'module'
                        }
                    }
                },
                {
                    loader: 'sass-loader',
                    options: {
                        additionalData: `$cdnURL: '${process.env.NEXT_PUBLIC_CDN_URL}';`
                    }
                }
            ]
        })
        return config
    }
})

As you can see, I remove the style-loader, because I am getting this error. So when I remove this, I am able to proceed. I was able to add the environment variable; however, I am overriding the default scss configuration of next. So whenever I am trying to build my project, I got this warning:

Warning: Built-in CSS support is being disabled due to custom CSS configuration being detected.
See here for more info: https://err.sh/next.js/built-in-css-disabled

The application is running, but the scss was not bundled as a module I believe.

So is there anyway wherein I can add my environment variable to scss without overriding next.js configuration as a whole?

Rich
  • 3,928
  • 4
  • 37
  • 66

1 Answers1

1

Instead of adding an additional configuration for sass-loader you need to modify the built in one.

There is no official way to modify it yet, but the config that is passed to you contains the default, all you need to do, is to search for the specific loader and modify it.

This example is based on Next.js v9.5.2. Instead of using additionalData, you need to use prependData since that is what on the API Schema of sass-loader

config.module.rules
  .filter((rule) => !!rule.oneOf)
  .forEach((rule) => {
    rule.oneOf
      .filter((oneOfRule) => {
        return oneOfRule.test
          ? oneOfRule.test.toString().includes('sass') &&
              Array.isArray(oneOfRule.use) &&
              oneOfRule.use.some((use) => use.loader.includes('sass-loader'))
          : false;
      })
      .forEach((rule) => {
        rule.use = rule.use.map((useRule) => {
          if (useRule.loader.includes('sass-loader')) {
            return {
              ...useRule,
              options: {
                ...useRule.options,
                prependData: `$cdnURL: '${process.env.NEXT_PUBLIC_CDN_URL}';`,
              },
            };
          }
          return useRule;
        });
      });
  });

On Next.js v9.5.4 and later, you should use additionalData.

felixmosh
  • 32,615
  • 9
  • 69
  • 88
  • 1
    Add a few amendments to your code, but the base and the logic is still there. Basically, not all the `oneOfRule` variable has `test` property, so I needed to check first. And the `additionalData` is not part of the interface of `option` of `sass-loader`, so I needed to change it to `prependData`, and it works. Thanks! – Rich Sep 17 '20 at 16:22
  • Update the answer for **Next.js v9.5.4** – Rich Oct 08 '20 at 16:45