DEV Community

Cover image for The simple way to use Scoped and Global SCSS in Next.js
VladymyrPylypchatin
VladymyrPylypchatin

Posted on • Edited on • Originally published at Medium

The simple way to use Scoped and Global SCSS in Next.js

When I started working with next.js I had difficulties with styling components. Although it has a default way of styling called CSS in JS, I preferer Create React App approach. When you can write SASS/SCSS styles in separate files and scope it to the file or make it global.

The main problem was that the default next-sass package allowed only to use ether scoped styles or global. There wasn’t a simple way how to use it them both.
So after some research and development, I figure out how to make it work with both of them. So I want to share with you how to make it, so you can save some of your time.

Warning!

This method doesn't work with the latest next.js updates.I recommend using the approach in this comment https://dev.to/vladymyrpylypchatin/comment/m7fg

High-Level Overview

First of all, we will need to install next-sass and node-sass packages in our project. Then we will need to write the custom configuration for webpack in the next.config.js to make these packages working as we want.
After these steps, you will be able to just use import styles from component.scss to make scoped to component styles. Or import filname.global.scss to use global styles into a component.
Let’s take a look at the details.

Install dependencies

Run these commands to install packages @zeit/next-sass and node-sass.

npm install --save @zeit/next-sass node-sass

or


yarn add @zeit/next-sass node-sass

Setup next.js configuration

First, you need to create a file next.config.js It is a predefined name so this file should have exactly this name otherwise it won’t work. next.config.js is a file where we can configure our next.js application and tweak default webpack configs.
Paste this code into your next.config.js, save it and restart your development server.

const withSass = require('@zeit/next-sass');
module.exports = withSass({
  cssModules: true,
  cssLoaderOptions: {
    importLoaders: 2,
  },
  webpack: config => {
    config.module.rules.forEach(rule => {
      if (rule.test.toString().includes('.scss')) {
        rule.rules = rule.use.map(useRule => {
          if (typeof useRule === 'string') {
            return { loader: useRule };
          }
          if (useRule.loader === 'css-loader') {
            return {
              oneOf: [
                {
                  test: new RegExp('.global.scss$'),
                  loader: useRule.loader,
                  options: {},
                },
                {
                  loader: useRule.loader,
                  options: { modules: true }
                },
              ],
            };
          }
          return useRule;
        });
        delete rule.use;
      }
    });
    return config;
  },
});

How to use

Scoped styles

To use scoped styles just create a file *.scssand import it to a react component. The imported variable will store an object with style’s class names mapped to its hash versions.
Component.scss

.someScssClass {
    height: 100px;
    backgrond: red;
    ...
}

Component.jsx

import React from 'react';
import styles from './Component.scss';
const Component = () => {
    return (
        <div className={styles.someScssClass}>
        ...
    </div>
    );
};

Global styles

To make global styles you need to create a file with this name convention *.global.scss and import it to the React component.

styles.global.scss

.globalClass{
    ...
}

Component.jsx

import React from 'react';
import '../{path}/styles.global.scss';
const Component = () => {
    return (
        <div className="globalClass"}>
       ...
    </div>
    );
};

That’s it. Now you can easily use both global and local SCSS styles in your project. I hope this tutorial saved you some time.
I am a freelance software engineer who loves to develop web and mobile applications, sass. Subscribe to get insights and lessons learned while building my freelance business and SasS projects :)

JavaScript
Nextjs
React
Web App Development

Top comments (10)

Collapse
 
f2aldi profile image
Aldi

Hello, i got error when add this to next.config.js
Said this :
TypeError: Cannot read property 'toString' of undefined
at /Applications/XAMPP/xamppfiles/htdocs/esteh/academy-landing/next.config.js:9:21

Why is there are error?

thanks

Collapse
 
vladymyrpylypchatin profile image
VladymyrPylypchatin

This happens after the next.js update. I recommend using the package @webdeb/next-styles. It makes using scoped *.scss files as simple as in CRA.

The example of the next.config.js using this package:

// next.config.js
const withStyles = require('@webdeb/next-styles')

module.exports = withStyles({
  sass: true, // use .scss files
  modules: true, // style.(m|module).css & style.(m|module).scss for module files
})

I hope this will help you :)

Collapse
 
chukwu3meka profile image
Chukwuemeka Maduekwe

do i still need to run this command
"npm install --save @zeit/next-sass node-sass"
after installing this package

Thread Thread
 
estebanrao profile image
Esteban Rao • Edited

According to nextjs.org/docs/basic-features/bui... you just need to run npm install sass / yarn add sass / pnpm add sass

Thread Thread
 
chukwu3meka profile image
Chukwuemeka Maduekwe

thanks

Collapse
 
tsabary profile image
Tsabary

First, you need to create a file next.config.jIt a predefined name so this file should have exactly this name otherwise it won’t work.

should the file name be next.config.jIt? Or next.config.js? I think you had a typo there no?

Collapse
 
vladymyrpylypchatin profile image
VladymyrPylypchatin

You are right, the correct name is next.config.js

Collapse
 
dance2die profile image
Sung M. Kim

Hi VladymyrPylypchatin.

Can I request to fix the code formatting & highlights?

Please check out the Editor Guide on how :)

Collapse
 
vladymyrpylypchatin profile image
VladymyrPylypchatin

Oh... Sure. I thought it is a draft

Collapse
 
dance2die profile image
Sung M. Kim • Edited

Thanks.

If you use v1 editor, setting frontmatter published: true will publish
For v2 editor, publish button will publish the content :)