vercel / vercel/next.js

next build --webpack drops semicolon after CSS @layer statement

Open
#94,191 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

CSS Output Webpack
Dominant language
JavaScript
Stars
142k
Forks
32.4k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Link to the code that reproduces this issue

https://github.com/Poliklot/next-css-layer-statement-semicolon-repro

To Reproduce
git clone https://github.com/Poliklot/next-css-layer-statement-semicolon-repro.git
cd next-css-layer-statement-semicolon-repro
npm install
npm run build
npm run inspect-css

The reproduction is intentionally small. The important source file is src/styles/layers.scss:

@layer reset, tokens, base, components, utilities;

It is imported before other global SCSS files in src/app/layout.tsx.

Current vs. Expected behavior

Current behavior: next build --webpack removes the semicolon after the CSS cascade layer statement in the emitted production CSS.

The built CSS starts like this:

@layer reset, tokens, base, components, utilities
@layer reset{*,:after,:before{box-sizing:border-box}body{margin:0}a{color:inherit;text-decoration:none}}

The layer statement is missing its required ; before the following @layer reset { ... } block. In browsers this makes the output invalid around the layer statement boundary, and the following reset layer can be ignored. In a real app this caused production-only styling differences: anchors became underlined again and form controls fell back to default/content-box sizing, while development looked correct.

Expected behavior: the emitted CSS should preserve a valid boundary between the layer statement and the following layer block, for example:

@layer reset, tokens, base, components, utilities;@layer reset{*,:after,:before{box-sizing:border-box}}

or otherwise output a valid equivalent CSS representation.

Provide environment information
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.3.0: Wed Jan 28 20:54:46 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T6000
  Available memory (MB): 16384
  Available CPU cores: 8
Binaries:
  Node: 20.19.0
  npm: 11.13.0
  Yarn: 1.22.22
  pnpm: 8.7.6
Relevant Packages:
  next: 16.3.0-canary.31 // Latest available version is detected (16.3.0-canary.31).
  eslint-config-next: N/A
  react: 19.2.6
  react-dom: 19.2.6
  typescript: 6.0.3
Next.js Config:
  output: export
Which area(s) are affected? (Select all that apply)

CSS, Output, Webpack

Which stage(s) are affected? (Select all that apply)

next build (local), Other (Deployed)

Additional context

This reproduces with the latest canary available at the time of testing (next@16.3.0-canary.31) and with next build --webpack.

The issue was originally noticed in a statically exported app deployed to Apache, but the linked reproduction shows that the invalid CSS is already emitted by the local production build before deployment.

A workaround is to avoid the layer statement form and declare empty layer blocks instead:

@layer reset {}
@layer tokens {}
@layer base {}
@layer components {}
@layer utilities {}

That keeps the emitted CSS valid in the affected app.

I searched for related issues before opening this. Existing issues like #64921, #79531, and #68476 look related to CSS order / cascade layers / cssnano, but I could not find an issue for this exact missing semicolon after a standalone @layer statement in a webpack production build.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproduction's src/styles/layers.scss and src/app/layout.tsx, then run npm install, npm run build, and npm run inspect-css to inspect the emitted CSS. Trace the next build --webpack production CSS path responsible for removing the separator, and verify that the standalone @layer statement remains valid before the following layer block.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nextjs, scss, webpack
Domain
build-system, frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.