Leveraging Global SCSS Variables in Next.JS with SASS

In my Next.js Application, I have a global CSS file named main.scss imported in the pages/_app.js file.

_app.js

import '../global-styles/main.scss'

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

The styles from this global file work perfectly.

I also have modular SCSS files attached to components, using the naming convention [component].module.scss.

In one of the files that I import into main.scss, specifically variables.scss, I have defined a variable.

variables.scss

$mobile: 750px;

main.scss

@import './fonts.scss';
@import './variables.scss';
@import './global.scss';

However, when I attempt to use this variable in one of my modular CSS files, I encounter an error.

./module-styles/navbar.module.scss (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-3-1!./node_modules/postcss-loader/src??__nextjs_postcss!./node_modules/resolve-url-loader??ref--5-oneOf-3-3!./node_modules/sass-loader/dist/cjs.js??ref--5-oneOf-3-4!./module-styles/navbar.module.scss)
SassError: Undefined variable: "$mobile".
        on line 19 of /Users/Parv/Documents/reactx/module-styles/navbar.module.scss
>>         @media (max-width: $mobile) {

   ---------------------------^

My concern is, why are the global variables I declare in my main.scss file not being recognized?

Answer №1

To implement this feature, simply insert the following code snippet into your next.config.js file and then restart your application:

const path = require('path')
    
module.exports = {
    sassOptions: {
        includePaths: [path.join(__dirname, 'styles')],
        prependData: `@import "main.scss";`
    }
}

Answer №2

One convenient method is to include a file with variable import and set an alias in tsconfig

sassOptions: {
    includePaths: ['./src'],
    prependData: `@import "~@styles/variable.scss";`,
}

Update:

To implement this, add the following code to next.config.js (create the file if it doesn't exist)

module.exports = (phase, {defaultConfig}) => {
    if ('sassOptions' in defaultConfig) {
        defaultConfig['sassOptions'] = {
            includePaths: ['./src'],
            prependData: `@import "~@styles/variables.scss";`,
        }
    }
    return defaultConfig;
}

Additionally, make sure to add an alias in tsconfig.json

"baseUrl": ".",
"paths": {
    ...
    "@styles/*": [
        "src/styles/*"
    ],
    ...

Finally, create a file at the path: src/styles/variable.scss. In variable.scss, you can then import other scss files.

Answer №3

Although this issue is not specific to Next.js, it actually pertains to the functionality of sass-loader. Whenever a scss file is imported into a js file, it creates an isolated environment for Sass, meaning that there are no truly "global variables."

As a result, you must ensure that the variables.scss file is imported into every scss file that utilizes any of the variables.

Important side note: It's crucial that shared scss files (such as your variables.scss) do not contain regular CSS styles, as this would lead to unnecessary duplication with each import.

Answer №5

To overcome this issue, I found a workaround by including my global variables in next.config.js. While it may not be the most ideal solution, it does get the job done.

module.exports = {
  sassOptions: {
  includePaths: [path.join(__dirname, 'styles')],
  prependData: `
       $primary-font-regular: 'Gotham';
       $primary-font-medium: 'Gotham';
    
       $default-font-size: 16px;
    
       $h1: 5.208vw;
       $h4: 1.458vw;
    
       $primary-color: #000000;
       $gray: #CCCCCC;
  `,

  },
};

If you're interested, you can check out further details at: https://github.com/vercel/next.js/pull/12277

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error with Hydration Caused by Conditional Rendering in Client-Side Component

Having issues with conditional rendering in my client components. Every time I do conditional rendering based on a cookie value, I keep getting this error: react-dom.development.js:7076 Uncaught Error: Hydration failed because the initial UI does not match ...

When you hover over an image, both the image's opacity and the color of the title beneath it change. However, if the title expands to two lines, it messes up

I am currently working on a project where I have an image and a title displayed below the image. My goal is to change the color of the text when hovering over the image, as well as adjust the opacity of the image. Additionally, when hovering over the title ...

The Autocomplete feature from the @react-google-maps/api component seems to be malfunctioning as it returns

I'm encountering some difficulties with the Autocomplete component in @react-google-maps/api. While Autocomplete is working and displaying options, clicking on an option fills the input box but I'm only getting 'undefined' from the Plac ...

Guide on setting up redux store from server component using next.js and app router

I'm currently working with Next.js 13, React, and Redux to handle state management. My main objective is to fetch initial data on the server side and present it on the client side. Although I assumed this would be a typical approach with Redux and Ne ...

varying heights in bootstrap columns

My goal with utilizing the grid system of Bootstrap 3 is to achieve the following visual layout: View my envisioned image here. However, when using the normal row and col structure, I end up with a different result: See what I actually get here. Is there ...

Changing the appearance of a website by switching CSS stylesheets according to the size of the browser

Trying to build two versions of my website: one for mobile devices or small browsing windows, and another for large browser windows. Looking to link HTML to different style sheets based on browser size. Current attempt in code only addresses total screen ...

Error encountered in Webpack 4 when trying to compile node modules CSS file: Unexpected .(dot) token

I am currently in the process of transitioning my React project from client-side rendering to server-side rendering. Unfortunately, I have encountered an issue with my webpack configuration for CSS that was working perfectly fine in my original project (c ...

ReactJS encountered an error: Module Build failed due to a SyntaxError caused by an unexpected token '<'

When I attempt to compile my ReactJS code, an error is thrown. Although I have experience with ReactJS, this specific error is new to me (shown below). ERROR in ./kapiche/@kapiche_react/teacher/login.jsx Module build failed (from ./node_modules/babel-load ...

The correct way to use the useState hook for implementing an icon in React

My attempt at implementing a feature in React allows users to see active feedback on the screen by changing its icon when clicked. How can I make it change to another icon (e.g. from Box to BoxChecked) once it is clicked? Note: I believe this code line i ...

Error: Unable to modify the value of a protected property '0' in the object 'Array'

I am facing a challenging issue with implementing a Material UI slider in conjunction with Redux. Below is the code for the slider component: import { Slider } from '@material-ui/core' const RangeSlider = ({handleRange, range}) => { ...

Creating an Android application that integrates HTML styling efficiently

I currently have a social networking site with a mobile web version, and my goal is to package that view into an Android app and potentially enhance it with a custom splash screen. Essentially creating a branded browser window. If you have any tips or adv ...

Positioning the image to appear behind the Canvas

As I near the end of the game, I'm encountering an issue where the background image overlaps the Canvas. How can I resolve this problem? -Translated by Google Link to game Link to game with background ...

Ways to quickly change a class when clicking (without waiting for mouse button release)

Is there a way to instantly change the color of my span element when it's clicked by the user, rather than waiting for the mouse button to be released? This is the CSS code I'm using for the class: span.active{ color:#bdbcae; } I've tri ...

The paths of youngsters and the application of conditional styling

Here is the scenario I am dealing with: <div class="parent"> <div class"routeA"> <div class="header"> <li></li> <li class="p-highlight"></li& ...

Creating a scrolling sidebar in Bootstrap 4

Today I learned about CSS Bootstrap 4 and created my template with a sidebar. However, when there are many menus, I want the sidebar to show a scrollbar. I am looking for help on how to make a scrollbar appear on my sidebar template. Below are my HTML and ...

New to CSS Media Queries? Discover the Correct Way to Define Element Height!

Sorry for the oversized images! I'm diving into media queries for the first time. When I adjust my browser window to 320px, here's how my site displays: This is what I want it to look like on mobile phones. However, when I view it on my iPhone, ...

Scrolling animations do not support the Translate3d feature

I'm struggling to implement a smooth scroll effect on the header of my website. My approach involves using transform:translate3d for animation, with the goal of keeping the header fixed at the top and moving it out of view as the user scrolls down. I ...

Launch a Next.JS web application utilizing Yarn on Google App Engine

I'm in the process of deploying a web application that was constructed using templates provided by a friend. I don't have much experience with React/NextJS frameworks, so I'm uncertain about the distinctions between yarn and npx. When runni ...

changing the elements' classes by using a carousel

Having trouble with a custom carousel and unable to use the standard Bootstrap carousel. This is how my code is structured: Images: <img src="1.img"/> <img src="2.img"/> <img src="3.img"/> Prev / Next buttons: <div class="left ...

What is the process for using preventDefault on an event when the element id is provided as the argument?

I created a function that gets called when a button is pressed. The function takes the button's id as an argument, but I need to use the 'preventDefault' method on the button itself. As far as I know, I have to change the function's ar ...