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

Protecting the build directory while implementing actions/checkout@v2

My self-hosted GitHub runner is configured to deploy a Next.js app by checking out the repository, building, and restarting pm2. The issue arises when the actions/checkout@v2 step triggers, as it deletes all files in the repository, including the crucial ...

"Discover the power of Next.js by utilizing dynamic routes from a curated list

I am working on a Next.js application that has a specific pages structure. My goal is to add a prefix to all routes, with the condition that the prefix must be either 'A', 'B', or 'C'. If any other prefix is used, it should re ...

What is the best way to incorporate my theme classes into my React component for custom styling?

Struggling to customize my React header buttons as I can't seem to apply my classes function that utilizes useStyles(). The error seems to be coming from: className: {classes.menuButton} within my getMenuButtons function. const useStyles = makeStyles ...

Encountering browser freezing issues with a Next.JS app when trying to add an input field

I am currently utilizing Next.JS to construct a form with two inputs. I have followed the traditional React approach for input text reading and validation. "use client" import { firebaseApp } from '@/app/firebase'; import React, { useCa ...

Conceal virtual keyboard on mobile when in autocomplete box focus

I would like the keyboard to remain hidden when the autocomplete box is focused or clicked, and only appear when I start typing. The code below currently hides the keyboard when any alphabets or numbers are pressed. However, I want the keyboard to be hidd ...

What is the best way to display two items side by side from a list of items in HTML?

I have a list of items that are displayed in `webView` with 4 elements per row. However, for `mobileView`, I would like to show only 2 elements in each row. Below is an example from my HTML file: <div class="row my-3 cust-heading" style="margin-left: 3 ...

Unsuccessful response: An error was encountered with status code 400 in the new ApolloError

I'm currently developing an application that utilizes NestJS for the backend with GraphQL and Postgres, while the front end is in Next JS. I've encountered an error when trying to call a mutation from the front end. Out of all the mutations, onl ...

Is it compulsory for all pages to be built with react?

I am diving into the world of web development by creating my own website from scratch using React and Node.js with Next.js. I'm curious if it's possible to build certain sections, like the registration page, without using React. I wonder if optin ...

Queries cannot be invalidated if any of the URL parameters are modified

Utilizing React Query, I retrieve a dataset and display it in a table. The table incorporates pagination and a data count per page. const {push, query} = useRouter(); const {page = 1, size = 10, ordering} = query; const {data: response, isLoading, isError, ...

Enhancing create-react-app to handle .mjs files using webpack

I am currently facing an issue while using the Twitch npm package from our project. When deploying via create-react-app / react-scripts, there are some problems that arise. It seems that the webpack configuration bundled with create-react-app does not sup ...

Incorporating React build files into a version control system

As I attempt to include the build files produced by running npm run build in a React App to a Git repository, I encounter an issue. The files generated through npm run build are directly utilized by my Django backend server. However, my backend and fronte ...

Achieve the effect of making the Bootstrap JS Collapse text bold after it has been

Is there a way to make Bootstrap JS Collapse text Bold after it has been clicked on? <tr data-toggle="collapse" data-target="#demo8" class="accordion-toggle"> <td> <div class="fa ...

Tips for including multiple spaces within a cell of a table

I've come across an issue while working on a table and attempting to insert text with multiple spaces. For example, I want to add the text HELLO<1stSPACE><2ndSPACE>WORLD. However, when I enter it as HELLO WORLD, it only displays with a single s ...

Attempting to link various functions in my component consecutively

Attempting to link numerous actions together in my react component poses a challenge: componentDidMount() { dispatch(Actions.fetchUser(userId)).then(() => { dispatch(Actions.fetchAbc(abcId)).then(() => { dispatch(Actions.fetchDef(defId)) ...

JavaScript opacity adjustments not achieving desired outcome

My attempt to make this sub menu fade in and out upon button press is not working as expected. It should fully fade in shortly after clicking 'help' and completely fade out when clicking 'back'. Is the problem with the method I'm u ...

The Chakra UI Modal overlay consistently envelops the entire screen

<> <Button onClick={onOpen}>Trigger modal</Button> <Modal onClose={onClose} isOpen={isOpen} isCentered> <ModalOverlay /> <ModalContent> <ModalHeader>Modal Title</ModalHeader> <Moda ...

What makes the nav class different from the navbar class in Bootstrap?

Recently, I delved into learning about bootstrap and web development. To my surprise, I stumbled upon the nav and navbar classes in bootstrap 4. I'm curious to know what sets them apart from each other and when it's best to use one over the other ...

Customizing PrimeReact Styles

I've been on a quest to find the perfect solution for customizing the default 'Nova' theme used in Prime React. While I know there is a theme designer available for purchase, I'd prefer not to go that route. In the past, I found myself ...

Webpack encounters difficulty resolving non-js `require`s located within node_modules

In my Next.js project, I have set up the configuration to handle imports ending in .web.js, which works fine except for files within the node_modules directory. For this setup, I adjusted the webpack config by setting resolve.extensions = ['.web.js&ap ...

Google Bar Graphs Cannot Display Decimal Values

Having an issue with my bar chart from Google Chart not displaying float numbers. Other types of bar charts provided by Google Chart work fine, but this specific type doesn't show the float numbers. Here is the code I have written: http://jsfiddle.ne ...