next.js: Next 13 + experimental app dir + Tailwind hot-reload of classes doesn't work

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

❯ npx next info

Operating System:
  Platform: darwin
  Arch: x64
  Version: Darwin Kernel Version 21.6.0: Thu Sep 29 20:12:57 PDT 2022; root:xnu-8020.240.7~1/RELEASE_X86_64
Binaries:
  Node: 16.16.0
  npm: 8.11.0
  Yarn: 2.4.3
  pnpm: N/A
Relevant packages:
  next: 13.0.7-canary.3
  eslint-config-next: 13.0.3
  react: 18.2.0
  react-dom: 18.2.0

Which area(s) of Next.js are affected? (leave empty if unsure)

No response

Link to the code that reproduces this issue

https://github.com/vercel/app-playground

To Reproduce

  • Grab latest version of Next.js with experimental app dir enabled (I’m using the playground example)
  • Load project, go to /streaming
  • In your editor, go to Product.tsx and edit a class with a width class w-* (go to line 75)
  • Swap w-1/3 for w-6/12 save and wait for hot-reload (don’t manually refresh the page)
  • You won’t see your new class applied, element will break due to class not being applied
  • Go back to editor and try now w-10/12, wait for hot-reload. Same result as above.
  • Set it now to w-6/12 and manually reload, you will see your class now (and it seems to be caching this class now)
  • If you repeat the steps above w-6/12 won’t fail anymore because it seems to be cached now somehow

Describe the Bug

Hot reloading of Tailwind CSS when you change classes in your code doesn’t work. Only works after you apply a new class and manually reload the page.

Bug in action: bug

Expected Behavior

Swapping Tailwind classes from elements should work when hot-reloading.

Which browser are you using? (if relevant)

Chrome 108.0.5359.98 (Official Build) (x86_64)

How are you deploying your application? (if relevant)

Locally (npm run dev)

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 44
  • Comments: 95 (16 by maintainers)

Commits related to this issue

Most upvoted comments

My problem looks like solved. I added this into the tailwind.config (excludes node_modules from purge):

  content: [
    //...
    "!./node_modules",
  ],

P.S.: Not sure if this solved my problem, other candidate was switching off the windows firewall.

I’m seeing this issue too.

The reproduction is simply:

  • Begin a new Next.js 13 project with app directory, using the next-create-app command.
  • Install tailwind and configure it.
  • Use any tailwind class in dev mode, then change the class to one you haven’t used.

I’m on macOS, so it’s not just a WSL issue.

The latest canary is broken in another way with an SSR rendering error, so not usable at the moment.

Edit: Ok, looks like this is a Firefox issue - it works for me in Chrome and Safari, but not in Firefox or Firefox Dev Edition. Odd.

Same here in Next v13.1.1

I fixed the problem for me by adding a proper HTML structure to my RootLayout, like this:

Before (app/layout.tsx):

import "../styles/globals.scss";
import Nav from "./Nav";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <Nav />
      <main>{children}</main>
    </>
  );
}

After(app/layout.tsx):

import "../styles/globals.scss";
import Nav from "./Nav";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
	<head></head>
	<body>
	  <header>
            <Nav />
	  </header>
	  <main>{children}</main>
	</body>
    </html>
  );
}

Since this issue is closed, what’s happening to the feedback here?

Still same issue for me V13.1.1

Putting in "!./node_modules", inside tailwind config content looks like fixed it for me:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx}",
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
    "!./node_modules",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

After trying for a while with all the suggestions, adding the following to your root layout file works:

import "../styles/dist.css";
import "tailwindcss/tailwind.css"; <-- add this

It works with 13.1.1 as well.

Same error on 13.0.7-canary.1. Seems to work on 13.0.6? Correct me if I’m wrong.

I’m on 13.0.6 and it doesn’t work. I just tried a fresh next.js installation based on the official tailwind guide, with the /app directory https://tailwindcss.com/docs/guides/nextjs#app-directory and it’s the same problem there (13.0.6).

I up- and downgraded between different next.js versions and there is a difference between 13.0.5 and 13.0.4, hot reload works works well with 13.0.4, but is broken with 13.0.5.

I’m seeing this issue too.

The reproduction is simply:

* Begin a new Next.js 13 project with app directory, using the next-create-app command.

* Install tailwind and configure it.

* Use any tailwind class in dev mode, then change the class to one you haven't used.

I’m on macOS, so it’s not just a WSL issue.

The latest canary is broken in another way with an SSR rendering error, so not usable at the moment.

Edit: Ok, looks like this is a Firefox issue - it works for me in Chrome and Safari, but not in Firefox or Firefox Dev Edition. Odd.

Confirmed this fixed it for me using Next 13.1.3 on macos. My layout structure is fine too. Trying the same stuff in Chrome / Safari hot-reloads completely fine and as expected. So it looks like I’ll be using Chrome until this resolves itself.

Edit: I will stick with Firefox; it’s the only non-shady browser out there.

For me it is working on 13.1.1. Make sure you are using the exact version "next": "13.1.1" instead of "next": "^13.1.1".

We land a fix in 13.0.8-canary.0. Could you upgrade to to see if the hmr is fixed for you?

The problem here is the layout structure, like @DerTyp876 mentioned. Making sure to have the proper structure solves the issue.

I can confirm the issue. Happens specifically on app directory + v13

Not fixed in v13.0.7-canary.4

Here is a potential fix (will fix ordering issue that may exist in addDir that did not exist elsewhere:

Search you node_modules for chunkFilename: ctx.isProduction ? "static/css/[contenthash].css" : "static/css/[name].css" which you will find in two files. In the line after, add this:

            insert: function (linkTag) {
                const previous = Array.from(document.head.children).find(link=>link.href===linkTag.href);
                const after = previous?.previousElementSibling;
                
                if (after) {
                    after.insertAdjacentElement(linkTag)
                } else {
                    document.head.appendChild(linkTag)
                }
              },

The whole section will then look like this:

new MiniCssExtractPlugin({
            filename: ctx.isProduction ? "static/css/[contenthash].css" : "static/css/[name].css",
            chunkFilename: ctx.isProduction ? "static/css/[contenthash].css" : "static/css/[name].css",
            insert: function (linkTag) {
                const previous = Array.from(document.head.children).find(link=>link.href===linkTag.href);
                const after = previous?.previousElementSibling;
                
                if (after) {
                    after.insertAdjacentElement(linkTag)
                } else {
                    document.head.appendChild(linkTag)
                }
              },
            // Next.js guarantees that CSS order "doesn't matter", due to imposed
            // restrictions:
            // 1. Global CSS can only be defined in a single entrypoint (_app)
            // 2. CSS Modules generate scoped class names by default and cannot
            //    include Global CSS (:global() selector).
            //
            // While not a perfect guarantee (e.g. liberal use of `:global()`
            // selector), this assumption is required to code-split CSS.
            //
            // If this warning were to trigger, it'd be unactionable by the user,
            // but likely not valid -- so we disable it.
            ignoreOrder: true
        })));

Then npm start dev again and see if things work. Let me know please!

[Edit: BTW, probably don’t need to ignoreOrder as my insert preserves the order. Also, the code is not ES5 in case someone from Next is looking at this – the code gets turned into a string and is not transpiled.]

@leerob I’ve tested your video and it seems that the colours have been generated somehow. If you try with a completely new colour like bg-emerald-200 or bg-[#FFD000] you’ll see that this colour is not applied.

You’ll see in this video that colours I’ve used previously are updated straight away but if I try a new colour like bg-yellow-200 in my case it is not generated. I have to refresh to make this colour available.

https://user-images.githubusercontent.com/1540635/213171154-4d346913-e109-40b6-8008-f6b6e42188ec.mp4

@reginpv this worked! I did a brand new build of next.js 13 with app directory using yarn create next-app --experimental-app

After that, I installed Tailwindcss:

yarn add -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Added the Tailwind directives to globals.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

And lastly, modified the tailwind.config.js file:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx}',
    './pages/**/*.{js,ts,jsx,tsx}',
    './components/**/*.{js,ts,jsx,tsx}',
    '!./node_modules',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

I previously had done this but it didn’t work when I did everything manually and started with just yarn add next-app. Weirdly, it works when I did it this way starting with yarn add next-app --experimental-app

Also, on next 13.0.8-canary.4 tailwind does not work at all, and no CSS is loaded. I will try 13.0.8-canary.0 and update this comment if I get something close to working

Update: 22-12-2022

On canary 13.0.8-canary.5 tailwind is still broken, and no CSS is loaded

@asheikho99 I tried your reproduction on a windows VM it works for me. I feel it’s another issue with windows specific based on the reports after reopening. I’d like to close this for now since it’s fixed for the original issue. We can track the windows one in the new issue.

@huozhi, I used Linux under WSL and it doesn’t work for me. So not just only Windows specific? Can you at least link the new issue so others can follow the core issue of it not refreshing/compiling classes?

Unfortunately @teddybee’s workaround didn’t work for me, it may be because I’m in a pnpm monorepo

Still broken on latest canary

I got the same error, it only works with classes already defined somewhere else.

Hi all, we are tracking the issue here instead: https://github.com/vercel/next.js/issues/43396#issuecomment-1405218446.

So, I looked into it more. Firefox does not reload a css file by the same name if you add it to the document.head. You can do one of two things: delete the link to css first and then add it back, or use a different name.

NextJS is using MiniCssExtractPlugin (see here).

Here are the network panel recordings for both:

Chrome: (note that is reloads the css file – twice) image

Firefox: (note that no css is reloaded) image

Tailwind classes don’t work, i am on nextjs 13.1.6.

@ngimdock I was testing today the latest version of NEXTJS creating a project from scratch, I did the configuration of the tailwindcss beta documentation with next 13 and the styles were not working. And it was because I put in the installation “use /src” in the project. Then looking for the error in stackoverflow, I noticed that when copying/pasting the tailwind.config.js, I forgot to change the path of the content. I feel SO Stup… XD

Source: Stackoverflow Comment

The issue does exist on 13.1.1 and 13.1.5 for me.

But I would also like to confirm the issue DOES happen on Firefox and DOES NOT happen on Chromium. I’m using ubuntu but i dont think that matters.

I inspected the requests on both browsers and it seems firefox isnt sending the css requests. See the screenshots below

image image

Another thing i noticed the request to / (happens on each refresh) returns different response on chrome versus firefox. Could be the same thing differently encoded/compressed which i’m not sure. Just helping with my little obsevations.

image image Edit: Looks like response is the same both browsers but showing as base64 on firefox network console. My bad.

So my thought is that @SheryConcepts, styles are probably being generated just not being pulled on refresh, on firefox.

Edit: Downgrading to 13.0.4 does eliminate the issue for me. Not a big fan of the downgrade though and also see a flinker of un-styled components when applying new generated classnames.

@andresev exactly how I did it!

It is still not working on 13.1.1.

experimental: {
	appDir: true,
}

Also, I found out enable appDir does affect TailwindCSS hot-reload of classes in pages folder.

Windows 10, didn’t work for me either on version 13.1.1.

Same issue.

Same here - version 13.0.6 still works. Version 13.0.7 is where it breaks and 13.1 does not fix it. Seems like turbopack and swc_core was updated for that 13.0.7 version. That may be the reason

For the record, this is mostly fixed for me (I haven’t thoroughly tested it yet) in canary version 13.0.8-canary.0. But I’m using it on a Mac M1.

Running under WSL on Windows 10, clean yarn install doesn’t work for me. New classes are not compiled in when saved.

    Operating System:                            
      Platform: linux                            
      Arch: x64                                  
      Version: #1 SMP Fri Apr 2 22:23:49 UTC 2021
    Binaries:                                    
      Node: 18.8.0                               
      npm: 9.2.0                                 
      Yarn: 1.22.19                              
      pnpm: N/A                                  
    Relevant packages:                           
      next: 13.0.8-canary.0                      
      eslint-config-next: 13.0.6                 
      react: 18.2.0                              
      react-dom: 18.2.0   

doesn’t seem to work for me when upgrading to 13.0.8-canary.0 but kept downgrading to 13.0.4 and started working again.

I have an issue as well with 13.0.6, hot reload often “loading” endless with a small project. No experimental app dir in my case. (node:17576) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 client/ listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit