Joel Hager
Joel Hager

Reputation: 3440

SCSS modules not loading in NextJS

I'm not sure what the problem is, as I've done this numerous times with no issues, so I'm thinking I messed something up. I'll show the Product.js component, and the module file, and please let me know if there's anything else I'm missing (for example, there's no next.config.js file either).

Thanks in advance!

Product.js

import { Card } from '@material-ui/core'
import styles from '../styles/Products.module.scss'

export default function Product({ product }) {
  console.log(product)
  return(
    <Card className="product">
      <img src={product.main_image} />
      {product.name && product.name}
    </Card>
  )
}

Products.module.scss file

.product {
  max-width: 300px;

  & img {
    width: 100%;
  }
}

Upvotes: 9

Views: 18330

Answers (4)

Ryan
Ryan

Reputation: 140

For anyone coming across this thread using Next.js 13 with Turbopack like I did, SCSS/Sass is not currently supported out of the box with Turbopack. Go into your package.json and remove --turbo from the line with your dev script until we get that functionality within Turbopack or a plugin. Or you can just deal with normal css modules, which work fine with Turbopack.

package.json (before)

  "scripts": {
    "dev": "next dev --turbo",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },

package.json (after)

  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },

EDIT Aug 2024: It looks like this might now be supported which means this may no longer be necessary. I have not tested this. https://turbo.build/pack/docs/features/css#sass-and-scss

Upvotes: 12

Yuriy Yakym
Yuriy Yakym

Reputation: 3931

For those trying to get scss modules working with Turbopack, it's possible to configure it this way in next.config.js

{
    // ...

    experimental: {
        turbo: {
            rules: {
                '*.svg': {
                    as: '*.js',
                    loaders: ['@svgr/webpack'],
                },
                '*.module.scss': {
                    as: '*.module.css',
                    loaders: [SASS_LOADER],
                },
                '*.scss': {
                    as: '*.css',
                    loaders: [SASS_LOADER],
                },
            },
        },
    },
}

For those willing to configure SASS loader:

const SASS_LOADER = {
    loader: 'sass-loader',
    options: {
        sassOptions: {
            includePaths: [path.join(__dirname, 'styles')],
        },
        additionalData: globalSassImports,
    },
};

Upvotes: 0

Andrii Khrystodulov
Andrii Khrystodulov

Reputation: 11

I had the same issue. I'm using NextJS13 experimental with /app folder.

I was using sass modules in my application. Everything was working fine, but when I ran npm run dev again it stopped working. I also saw the same issue on GitHub but there were no solutions. I didn't find the way how to fix this, so I create application again from scratch and it started working fine.

A possible solution could be importing styles directly to layout.tsx not to page.tsx For example:

(layout.tsx)

// Global application styles

import './reset.scss'
import './global.scss'

// fonts
import { inter } from './fonts'

// Import Layout components
import Navigation from "./Navigation"
import ToolboxLayout from './(toolbox)/layout'
import Toolbox from './(toolbox)/page'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html
      lang="en"
      className={inter.className}
    >
      <head />
      <body className='body'>
        <Navigation />
        <main className='main'>
          <ToolboxLayout>
            <Toolbox/>
          </ToolboxLayout>
        </main>
      </body>
    </html>
  )
}

(Navigation.tsx)

import styles from './Navigation.module.scss'



export default function Navigation () {
    return (
      <header className={styles.navigation}>
        <div className={styles.left}>
            <div className={styles.title}>
                <p>EuroDataCube</p>
            </div>
        </div>
        <div className={styles.right}>
            <div className={styles.buttons}>
                info
                settings
            </div>
        </div>
      </header>
    )
}
  

Upvotes: 0

buzatto
buzatto

Reputation: 10382

when using CSS module you should pass to className your styles object, and accessing the desired class:

import { Card } from '@material-ui/core'
import styles from '../styles/Products.module.scss'

export default function Product({ product }) {
  console.log(product)
  return(
    <Card className={styles.product}>
      <img src={product.main_image} />
      {product.name && product.name}
    </Card>
  )
}

this because CSS Module will generate an unique class name. Its class name won't be product, but something like [filename]\_[classname]\_\_[hash] (with a unique hash) to avoid name collision.

adding CSS module

Upvotes: 13

Related Questions