Integrate Sass, Global Style and CSS Modules in Gatsby websites

Photo by Iker Urteaga on Unsplash

Adding global styles to a Gatsby site is a piece of cake.

Using CSS modules with Gatsby is painless.

Integrating Sass with Gatsby is also a snap.

However, what if you want to use a combination of global styling, Sass framework, and CSS modules? There is more to it than simply following a recipe for each method, mix them together, and get the shiny site on the other side.

That’s the raison d’être for this article. But first, what’s the deal with the amalgam of global styling, CSS modules and Sass?

I think no matter what CSS practices you adopt, you’re not going to get away with global styling. It means that you only need to update one or two files when you need to make a site-wide change, instead of 100 pages.

CSS modules are not a must, but once you’ve gotten used to them, you’d wonder how you can work after all those years without it it. How do you feel when you can write CSS like you normally do without having to rack you brain over which unique class names to dozens of comparable elements?

Last but not least, Sass may come in handy when your site grows big enough that writing CSS becomes too painful. That’s a problem that I would love to have, and so I enlist the help of Sass.

Set up a demo

In the terminal, navigate to the parent directory where you want to store your project files. Create a new site based on the Hello World starter theme.

This will create a new folder named sass-integration inside the current directory.

Navigate to the sass-integration folder. If you have installed Visual Studio code , run code . to open this folder in this text editor.

Use component-scoped CSS

Luckily, Gatsby works out of the box with CSS Modules because it was built by kind folks before us who got enough with class name collision.

First, create a new directory called components at the root of your project. Inside it, create a new Container component and import a CSS module.

You’ll notice that the CSS module file shares the same name as the component file, and has an extension of .module.scss. That's how we tell Gatsby that we want to use component-scoped CSS.

And in case you are wondering if the .scss extension is a typo, it's not. You can absolutely use Sass/SCSS files as modules too.

In the next step, we are going to install some extra plugins to compile the into CSS. At run time, what Gatsby gets is CSS files, not SCSS so it should work correctly.

Next, create an SCSS module at src/components/container.module.scss. It doesn't have to be in the same directory as the Container component, but this makes it easier to get hold of your site architecture.

Integrate Sass with Gatsby

We’ve created a Sass file in the previous step, but notice that there is nothing Sass about it. The file just contains pure CSS syntax. That’s because we haven’t installed plugins that will help compile Sass into CSS for us. Without them, our website will fail because the browser can’t read Sass.

Install gatsby-plugin-sass, the official Sass compiler for Gatsby and node-sass.

Then install sass as a development dependency. The reason why it is not a production dependency is because it is only needed for gatsby-plugin-sass to interpret Sass. It will make no presence in production.

In the gastby-config.js file, set up the configurations for gatsby-plugin-sass as followed:

By default, gatsby-plugin-sass uses the node implementation of Sass ( node-sass). The module works fine, except that it doesn't support loading built-in Sass modules with @use rule, and we are going to use that in our Sass file later on.

In Sass, the @use rule is used to load other Sass stylesheets. You can use @import in its stead, just like in CSS. However, the @import rule is heading towards its end in the next few years and even the Sass team warn against using it.

From my experience, it’s always worth spending a little bit more time to make sure that your site is as future forward as it could be.

That aside, what does the data option do? It will pass the @use rule into every SCSS file, and at the same time it namespace the variables module as just var.

For example, you have a Sass file that defines all the global variables like font family, site width, font color, background color etc.

You are going to load them in all the stylesheets to ensure design consistency. But who wants to remember write @use "src/styles/variables in dozens of stylesheets?

With the data configuration in Gatsby config, now you don't have to write that @use rule over and over again. You only have to write the namespace to load variables, functions and mixins from the variables module.

If that doesn’t make sense, don’t worry. Create a new stylesheet at src/styles/_variables.scss.

Please note that there is an underscore in front of the file name. That tells the Sass engine that this _variables.scss file is meant to be loaded as modules. It won't be generated into CSS unless you import it into another Sass file as partial. Any file loaded using the @use rule is called a partial.

When loading it with the @use rule, you can leave out the underscore.

Add style to this _variables module:

Then modify the Container CSS module to use the $bgcolor variable above:

Render Sass in Gatsby

We’ve technically integrated into Gatsby, but how can we tell if it works or not?

Create a new file named about-sass.js under src/pages directory. In this file, import and render the Container component like below:

Now, run the command gatsby-develop and go to [localhost:8000/about-sass](http://localhost:8000/about-sass) and you should see Sass being applied safe and sound.

Global variables should be defined outside any rules. It’s a good practice to define all global variables in its own file, named _global.scss, and include the file with @rule keyword.

But we haven’t added global styles

That’s right. Our about page above may be a special snowflake, but not that special. It should still adhere to certain site-wide styles to ensure a consistent brand identity.

To enforce a global style, create a new file gatsby-browser.js at the root of your directory. The name gatsby-browser is important, because it tells Gatsby that we want to implement Gatsby browser APIs and interact with the client-rendering of Gatsby.

Create a new stylesheet src/styles/global.scss and import it into the gatsby-browser.js.

Inside the global stylesheet, specify the background color property for the body element:

Then comment out the background color in the Container CSS module.

Restart the server and you should see the lavender blush color applied on the index page as below.

But I think our about page still deserves to stand out like the original plan.

In the _variables.scss, and a new variable:

After that, add back the background color property for the Container CSS module.

Switch back to your Gatsby website and navigate to the about page to see the little magic.

To recap, we’ve had quite a ride just for a the sake of CSS styling:

  • We configure our Gatsby site to work with Sass.
  • We add not one, but two new SCSS files to our src/styles directory. One for global styling, one for storing variables.
  • We tell gatsby-browser.js to use the global.scss as a global stylesheet.
  • We use the wonderful CSS modules to style components selectively and at the same time make use of the Sass variables.

You may exclaim: That’s so overkill. Let’s come back in a few months, when your beautiful, blazing fast Gatsby site has grown beyond leap and bounds, and see if still think so.

A web developer who lives with poor internet and always thinks of a new way to improve your site speed by 0.1%. Love automation in any form.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store