Next.js Global CSS cannot be imported from files other than your Custom <App>
Asked Answered
I

14

70

My React App was working fine, using global CSS also.

I ran npm i next-images, added an image, edited the next.config.js file, ran npm run dev, and now I'm getting this message:

Global CSS cannot be imported from files other than your Custom <App>. Please move all global CSS imports to pages/_app.js.
Read more: https://err.sh/next.js/css-global

I've checked the docs, but I find the instructions a little confusing as I am new to React.

Also, why would this error happen now? Do you think it has anything to do with the npm install?

I've tried to remove new files I've added along with their code, but this doesn't fix the problem. I've also tried what Read More: suggests.

My highest tier component:

import Navbar from './Navbar';
import Head from 'next/head';
import '../global-styles/main.scss';

const Layout = (props) => (
  <div>
    <Head>
      <title>Bitcoin Watcher</title>
    </Head>
    <Navbar />
    <div className="marginsContainer">
      {props.children}
    </div>
  </div>
);

export default Layout;

My next.config.js

// next.config.js
  const withSass = require('@zeit/next-sass')
  module.exports = withSass({
  cssModules: true
})

My main.scss file

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

my global.scss

body {
  margin: 0;
}
:global {
  .marginsContainer {
    width: 90%;
    margin: auto;
  }
}

The thing I find the weirdest is that this error came without changing anything to do with CSS or Layout.js, and it was previously working.

I've moved my main.scss import to the pages/_app.js page, but the styles still aren't coming through. This is what the _app.js page looks like

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

export default function MyApp({ Component, props }) {
  return <Component {...props} />
}
Immolate answered 31/3, 2020 at 1:0 Comment(0)
M
52

Use the built-in Next.js CSS loader (see here) instead of legacy @zeit/next-sass.

  1. Replace @zeit/next-sass package with sass.
  2. Remove next.config.js. Or do not change CSS loading in it.
  3. Move the global CSS as suggested in the error message.

Since Next.js 9.2 global CSS must be imported in Custom <App> component.

// pages/_app.js

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

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

To add styles only to a specific component or page you can use built-in support of CSS modules. (see here)

For example, if you have a component Button.js you can create a Sass file button.module.scss and include it in the component.

Martyrize answered 31/3, 2020 at 5:59 Comment(12)
Hey, I created and move the main.scss to that file previously, but it didn't work. I've tried again, but still not applying it. I have the following code in there: import '../global-styles/main.scss' export default function MyApp({ Layout, props }) { return <Layout {...props} /> }Immolate
@IndustryDesigns, try to use node-sass instead of @zeit/next-sass, I just tested it and updated the answer. Let me know if you have any specific errors in the command line or browser's console.Martyrize
This definitely made a difference. The global css is now working in _app.js. The last thing which is yet to work, which was previously working, is: :global { .marginsContainer { width: 90%; margin: auto; } }Immolate
I came to this answer because I'm trying to use scss inside a component. and apparently now I need to separate my scss file away from the components/my-component/ folder and put it in the pages? I'm confused..Quadrangular
is the .module. configurable?Myrlemyrlene
This the helped me! All you need is sass dependency (I am using next: 9.5.5) So do a npm i sass, add import '../your_path/your_name.scss'; to your pages/_app.js Then write some sassy styles!Sihon
Hey @NikolaiKiselev, do you know in which version they did this? where can I read more about this? "..Next.js dropped support of global CSS in files other than /pages/_app.js only in recent versions.."Rhaetian
@AntonDozortsev, since Next.js 9.2 (see Next.js 9.2 Blog Post).Martyrize
This answer is so outdated. Everything you are mention here is now deprecated.Cabrales
@PandukaNandara, could you please clarify what exactly has changed and is now deprecated?Martyrize
@NikolaiKiselev @zeit/next-sass is now deprecated. It is not recommended to use. The new SASS system in Next does not support for global styles. It only supports for module-based styles. Read more from here.Cabrales
@PandukaNandara, thanks for explaining. The answer suggests removing the @zeit/next-sass package and using CSS modules instead.Martyrize
C
20

Next.js stops complaining when your file has module in naming, e.g., changing import '../global-styles/main.scss'; to import '../global-styles/main.module.scss'; would fix the warning and you could have your styles in the global-styles, or for example, in your component.

No extra dependencies/configurations in next.config.js is required.

Callisto answered 25/11, 2021 at 10:14 Comment(0)
G
8

You can replace the opinionated (and overly-complex?) NextJs CSS loaders with your own. Here's a simple one for global css:

const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
  reactStrictMode: true,
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    // Find and remove NextJS css rules.
    const cssRulesIdx = config.module.rules.findIndex(r => r.oneOf)
    if (cssRulesIdx === -1) {
      throw new Error('Could not find NextJS CSS rule to overwrite.')
    }
    config.module.rules.splice(cssRulesIdx, 1)

    // Add a simpler rule for global css anywhere.
    config.plugins.push(
      new MiniCssExtractPlugin({
        experimentalUseImportModule: true,
        filename: 'static/css/[contenthash].css',
        chunkFilename: 'static/css/[contenthash].css',
      })
    )

    config.module.rules.push({
      test: /\.css$/i,
      use: !isServer ? ['style-loader', 'css-loader'] : [MiniCssExtractPlugin.loader, 'css-loader'],
    })
    return config
  },
}
Gladsome answered 30/7, 2021 at 14:55 Comment(4)
also, if there is a font being imported, we can file-loader as well to the rulesPurchasable
I found that this removed too many rules related to other types of files. But I successfully used this as a base to go through the oneOf rules and remove the Global CSS ones.Blacksmith
@Blacksmith could you please share your solution, I believe I have the same problem as youBrebner
@Dominic How to this with scss?Exorcist
M
4

Add this to your _app.js

import '../styles/globals.css'
Mitchel answered 12/10, 2021 at 3:14 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Nad
S
3

This node package provides a perfect solution for it. You can find it here

Steps to fix it:

1. Add package:

npm install next-remove-imports
or
yarn add next-remove-imports

2. Add this wrapper variable inside your next.config.js

const removeImports = require('next-remove-imports')({
   test: /node_modules([\s\S]*?)\.(tsx|ts|js|mjs|jsx)$/,
   matchImports: "\\.(less|css|scss|sass|styl)$"
 });

All it is doing is re-enabling global styling import rule for tsx|ts|js|mjs|jsx files

3. Wrap your next config export with this next-remove-imports wrapper. Something like this:

module.exports = removeImports((nextConfig)

4. Now restart your react app and you will be able to import CSS files inside any ts|js|js|jsx|mjs file or component.

Sheilahshekel answered 30/9, 2022 at 2:39 Comment(0)
S
2

For me the problem was because I had used two module.exports in my next.config.js file like this

const withPlugins = require('next-compose-plugins')
const sass = require('@zeit/next-sass')
const css = require('@zeit/next-css')

const nextConfig = {
    webpack: function(config){
    config.module.rules.push({
        test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
        use: {
        loader: 'url-loader',
            options: {
            limit: 100000,
            name: '[name].[ext]'
        }}
    })
    return config
    }
}

module.exports = withPlugins([
    [css],
    [sass, {
        cssModules: true
    }]
], nextConfig)

module.exports = {
    env: {
        MONGO_URI = 'your uri'
    }
}

. 1I modified it to change the export module like this.

const nextConfig = {
    webpack: function(config){
    config.module.rules.push({
        test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
        use: {
        loader: 'url-loader',
            options: {
            limit: 100000,
            name: '[name].[ext]'
        }}
    })
    return config
    },
    env: {
        MONGO_URI: "your uri"
    }
}

2then I deleted the second module.exports

Solitta answered 1/12, 2020 at 19:46 Comment(1)
Please read how common.js modules work. the second module.exports overrides the first one. Your first NextJS config practically does not get applied.Stenograph
S
2

Convert all your .css /.scss files to [filename].module.css / [filename].module.scss.

In your case it should be renamed to

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

Tested in high-level production grade projects.. Worked perfectly for me

Sargassum answered 9/3, 2023 at 16:5 Comment(0)
C
1

Try to include ".module" in your scss file name.

Change main.scss to main.module.scss

Example:

import styles from './todolist-profile-info.module.scss'
Conventional answered 4/1, 2022 at 5:54 Comment(0)
B
0

You did not need to do anything inside of next.config.js.

Let's assume you are using a global css like Bootstrap, meaning it contains css that is meant to be applied to your entire application and all the different pages inside of it.

Global css files have to be wired up to NextJS in a very particular fashion.

So inside of the pages/ directory you need to create _app.js.

It's critical that the file be named _app.js.

Then at the top of that file you would import Bootstrap css in the following manner:

import 'bootstrap/dist/css/bootstrap.css';

Then you would add the following:

export default ({ Component, pageProps }) => {
  return <Component {...pageProps} />;
};

So what is going on in that code?

Well, behind the scenes, whenever you try to navigate to some distinct page with NextJS, NextJS will import your component from one of the different files inside your pages/ directory.

NextJS does not just take your component and show it on the screen.

Instead it wraps it up inside of its own custom default component and that is referred to inside of NextJS as the App.

What you are doing by defining the _app.js is to define your own custom app component.

So whenever you try to visit a route inside a browser or your root route, NextJS is going to import that given component and pass it into the AppComponent as the Component prop.

So Component there is equal to whatever components you have in the pages/ directory. And then pageProps is going to be the set of components that you are intending to pass to your files inside of pages/.

So long story short, this thing is like thin wrapper around the component that you are trying to show on the screen.

Why do you have to define this at all?

Well, if you ever want to include some global css to the project, Bootstrap being a global css for example, you can only import global css into the _app.js file.

It turns out that if you try to visit other components or other pages, NextJS does not load up or even parse those files.

So any css you may have imported inside there will not be included in the final HTML file.

So you have a global css that must be included on every single page, it has to be imported into the app file because it's the only file that is guaranteed to be loaded up every single time a user goes to your application.

Don't forget that in addition to importing the css inside of _app.js, you also have to run an npm install bootstrap in your terminal.

You can read more on this here: https://nextjs.org/docs/messages/css-global

Blunge answered 30/7, 2021 at 14:46 Comment(1)
so every css files, you need to put in _app.js file , right ?Kosciusko
E
0

For me, i got this error because I had used improper naming for my project's parent folder, had used special characters in it,

like project#1,

after removing special chars, and changing the folder name to like project-1, the error got away.

Eloiseloisa answered 7/5, 2022 at 11:46 Comment(0)
T
0

In my case there was typo in navbar.module.css I've written navbar.moduile.css

Timmie answered 8/8, 2022 at 17:34 Comment(0)
S
0

This fixed for me, now I can use like: import Feed from "@components/Feed";

Saransarangi answered 2/11, 2023 at 9:48 Comment(0)
B
0

I'm not using SCSS but this is in the response to Philipp Fischer. This code is pretty much as Dominic wrote in his answer but I'm only removing the Global CSS rule and leaving the other rules in place as removing them all broke the inline css rules too.

    webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
        // Find and remove NextJS css rules.
        config.module.rules = config.module.rules.map(r=> {
            if(r.oneOf) {
                r.oneOf = r.oneOf.filter(test => {
                    if(!!test.use?.options?.reason?.startsWith('Global CSS')) {
                        return false
                    } else {
                        return true
                    }
                })
                return r
            } else
                return r
        })
        config.plugins.push(
            new MiniCssExtractPlugin({
                experimentalUseImportModule: true,
                filename: 'static/css/[contenthash].css',
                chunkFilename: 'static/css/[contenthash].css',
            })
        )
    
        config.module.rules.push({
            test: /\.css$/i,
            use: !isServer ? ['style-loader', 'css-loader'] : [MiniCssExtractPlugin.loader, 'css-loader'],
        })
Blacksmith answered 13/4, 2024 at 9:52 Comment(1)
@Philipp see answer above.Blacksmith
H
-1

you must for every component css/scss write navbar.module.css/scss/sass.Next js doesnt compile navbar.css/scss/sass. If hope my answer helps you !.

Housebreak answered 2/7, 2022 at 15:18 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Spurrier

© 2022 - 2025 — McMap. All rights reserved.