Next 15 update throws deprecation warning in console using sass
Link to the code that reproduces this issue
https://codesandbox.io/p/devbox/dark-architecture-go8s7s
To Reproduce
- install
sass(yarn add -D sass) - import styles from a SCSS module file
- Update Next to v15.0.0
Current vs. Expected behavior
A deprecation warning appears from sass : "Deprecation The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0". Is the deprecation related to a Next.js deprecated use of .scss modules that will be fixed ? Or does that mean that scss modules is deprecated in Next.js ?
Provide environment information
Operating System:
Platform: macOS
Version: 14.7
Binaries:
Node: 22.10.0
yarn: 1.22.19
Packages:
next: 15.0.0
sass: 1.80.1
Next.js Config:
reactStrictMode: true,
images: {
unoptimized: true
}
Which area(s) are affected? (Select all that apply)
Not sure
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
No response
We started getting this warning today too when trying out Next 15.
Looks like PR https://github.com/vercel/next.js/pull/70067 updated sass-loader to a version that is new enough to throw the deprecation warning, but didn't fully upgrade to v16 that would default to the modern Sass JS API.
I believe next updating sass-loader to v16+ would fix this. Our projects seem to work fine locally with the modern-compiler option turned on.
The SASS team even mentioned this already themself; https://github.com/vercel/next.js/discussions/67931
Hello, is there any way to just suppress the warning for the meantime?
@alfarodarwaynejay I believe you can use next config if you want to silence these warnings :
const nextConfig: NextConfig = {
sassOptions: {
silenceDeprecations: ['legacy-js-api'],
}
}
cf. https://nextjs.org/docs/app/building-your-application/styling/sass and https://sass-lang.com/documentation/breaking-changes/legacy-js-api/#silencing-warnings
gotta love open source 🙄
Also, :export { ... } in whatever.module.scss does not work anymore.
I have home-styles.module.scss:
$biggerTextFontSize: 20px;
:export {
biggerTextFontSize: $biggerTextFontSize;
}
But when running npm run dev, I get this error:
⨯ ./src/app/[locale]/(other)/(home)/home-styles.module.scss.module.css:7:1
Parsing css source code failed
5 |
6 | $sectionSeparatorSpace: 100px;
> 7 | :export {
| ^
8 | biggerTextFontSize: $biggerTextFontSize;
9 | sectionSeparatorSpace: $sectionSeparatorSpace;
10 | emphasizeColor1: $emphasizeColor1;
Unsupported pseudo class or element: export at [project]/src/app/[locale]/(other)/(home)/home-styles.module.scss.module.css:0:2
⚠ ./src/app/[locale]/(other)/(home)/home-styles.module.scss
Issue while running loader
SassWarning: Deprecation The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0.
More info: https://sass-lang.com/d/legacy-js-api
EDIT: this is because turbopack does not support :export (more here: https://nextjs.org/docs/architecture/turbopack#unsupported-features). Solution is to remove "--turbopack" after "next dev"
@JosipPardon This is unrelated to this issue
Check out the Sass article about it. sass-migrator just fixed it for me.
@emdagon That article is also about an unrelated deprecation
This issue is about Next’s webpack config loading the “legacy JS API” instead of the “modern JS API”
Hey, thanks for opening the issue. I'm considering:
- introducing an experimental option to use the upgraded sass
- silence the warning
We won't be able to upgrade it by default since it would require yet another major. Does that sound like a good compromise?
Yeaaah buddy
@feedthejim what are the implications of using an "experimental option to use the upgraded sass" vs "upgrade it by default"?
@tr1s an experimental option will allow people to opt-in to the new Sass API, which may require users to update their sassOptions at the same time
Upgrading it by default would require everyone to update their sassOptions, and might break their builds before they do so—so “upgrade it by default” would be a breaking change that can only be made in a semver-major release
@feedthejim love the idea, thanks 🙏
The error messages are demoralising despite turning the page on Harris.
This is my temporary solution:
- Install
sass-loader - Modify
next.config.js:
/**
* Webpack config modification adopted from https://github.com/vercel/next.js/issues/11629
*/
const regexEqual = (x, y) => {
return (
x instanceof RegExp &&
y instanceof RegExp &&
x.source === y.source &&
x.global === y.global &&
x.ignoreCase === y.ignoreCase &&
x.multiline === y.multiline
)
}
module.exports = {
webpack: config => {
const oneOf = config.module.rules.find(
rule => typeof rule.oneOf === 'object'
)
if (oneOf) {
const sassRule = oneOf.oneOf.find(rule => regexEqual(rule.test, /\.module\.(scss|sass)$/))
if (sassRule) {
const sassLoader = sassRule.use.find(
el => el.loader.includes('next/dist/compiled/sass-loader')
)
if (sassLoader) {
sassLoader.loader = 'sass-loader'
}
}
}
return config
}
}
Important! This is not compatible with Turbopack, I'm not using it.
This is my temporary solution:
- Install
sass-loader- Modify
next.config.js:/** * Webpack config modification adopted from https://github.com/vercel/next.js/issues/11629 */ const regexEqual = (x, y) => { return ( x instanceof RegExp && y instanceof RegExp && x.source === y.source && x.global === y.global && x.ignoreCase === y.ignoreCase && x.multiline === y.multiline ) } module.exports = { webpack: config => { const oneOf = config.module.rules.find( rule => typeof rule.oneOf === 'object' ) if (oneOf) { const sassRule = oneOf.oneOf.find(rule => regexEqual(rule.test, /\.module\.(scss|sass)$/)) if (sassRule) { const sassLoader = sassRule.use.find( el => el.loader.includes('next/dist/compiled/sass-loader') ) if (sassLoader) { sassLoader.loader = 'sass-loader' } } } return config } }Important! This is not compatible with Turbopack, I'm not using it.
thank but my case not work
sass options - prependData @use "src/styles/shome"; <- can't find stylesheet to import.
sass options - prependData @use "src/styles/shome"; <- can't find stylesheet to import.
I have the same problem, @import works, whereas @use throws this error using both Turbopack and webpack.
gotta love open source 🙄
Yeah, I don't think I have ever experienced an issue with closed source before.
Sarcasm aside, when there are so many closed source options, why are you choosing open source if you don't like it?
@alfarodarwaynejay I believe you can use next config if you want to silence these warnings :
const nextConfig: NextConfig = { sassOptions: { silenceDeprecations: ['legacy-js-api'], } }cf. https://nextjs.org/docs/app/building-your-application/styling/sass and https://sass-lang.com/documentation/breaking-changes/legacy-js-api/#silencing-warnings
If, like me, you did this but the warnings keep getting printed out when running next dev, remove the .next directory and it'll fix it.
I have installed sass-loader and created the following next.config: https://github.com/andreynovikov/galleria-js/blob/13db458e368757c68eca40bb3163f1354c3ffeb1/next.config.mjs#L39-L57
Hey everyone, thank you for waiting! Silencing the warning was added at PR https://github.com/vercel/next.js/pull/72632, and released to canary in v15.0.4-canary.12, and will be added to the next release!
@devjiwonchoi I came across a regression with your PR. When Turbo is enabled, other silenceDeprecations options from next config are ignored. My guess is that your Rust changes do not account for an existing array, but replaces silenceDeprecations with an array holding only ['legacy-js-api'].
The webpack implementation seems fine though.
should be fixed in 15.1 :) closing
This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.