Hugo building before Tailwind classes are created

In fast render mode, if a new Tailwind utility class is introduced (e.g a padding) that is not in hugo_stats.json when the watcher is running, then it does not reflect unless the build is cancelled and restarted. I have been monitoring this issue for a few months now since it occurs randomly.

I am using Bep’s Hugo Tailwind Starter Template files/config btw.

Hugo’s build is fast, very fast. It’s much faster than rebuilding TailwindCss, I don’t think this can be described as random…

I’m not sure

There is a watcher/config described elsewhere (I guess it’s in the starter you mentioned) that works great for me.

With the above, if you add a new TW class in HTML

  • Hugo builds.
  • If that build changes the hugo_stats.json, a new build will be triggered (which is very fast)

The fast build might be the issue. The last case was triggered by a px-2.5 utility class that did not apply until I restarted the server. I would be curious to know which setting is that in the watcher.

Note that there may be cases where the classes does not end up in the stats file (e.g. dynamic classes from JS), but in general I have found that it works great.

In your case I would

  1. Check if your px-2.5 class is written to the stat file
  2. If yes, I would verify that your watcher/cache buster setup is correct.

This looks sensible to me and in line with what I’m actually using:

  1. I will check that in VS code if it happens again.
  2. Here is my config
[modules]
  [[module.mounts]]
    source                                 = "assets"
    target                                 = "assets"
  [[module.mounts]]
    source                                 = "hugo_stats.json"
    target                                 = "assets/watching/hugo_stats.json"
[build]
  [build.buildStats]
    disableIDs                             = true
    enable                                 = true
  [[build.cacheBusters]]
    source                                 = 'assets/.*\.(js|ts)'
    target                                 = '(js|scripts|javascript)'
  [[build.cacheBusters]]
    source                                 = 'assets/.*\.(css|sass|scss)$'
    target                                 = '(css|styles|scss|sass)'
  [[build.cacheBusters]]
    source                                 = '(postcss|tailwind)\.config\.js'
    target                                 = '(css|styles|scss|sass)'
  [[build.cacheBusters]]
    source                                 = 'assets/.*\.(.*)$'
    target                                 = '$1'

I think the missing piece in your config is something like this:

[build]
  writeStats = true
  [[build.cachebusters]]
    source = "assets/watching/hugo_stats\\.json"
    target = "styles\\.css"

What the above says is

  1. When the hugo_stats.json file changes
  2. Clear any cache related to styles.css (that’s a regexp, so it matches any folder in the above example)

You can confirm this by

  1. Run hugo server --logLevel debug
  2. Add p-2.5 or something
  3. Check the log lines related to cache buster and see if it “busts” as expected.

Is this necessary with recent Hugo versions? I had removed it.

This is what I found (without writeStats = true) with px-3.5

DEBUG Rebuild for events ["WRITE \"C:\\\\Users\\\\arif\\\\hugo-site\\\\themes\\\\test\\\\layouts\\\\partials\\\\main\\\\meta.html\""]
DEBUG cachebuster: Matching "layouts/partials/main/meta.html" with source "assets/.*\\.(js|ts)": no match
DEBUG cachebuster: Matching "layouts/partials/main/meta.html" with source "assets/.*\\.(css|sass|scss)$": no match
DEBUG cachebuster: Matching "layouts/partials/main/meta.html" with source "(postcss|tailwind)\\.config\\.js": no match
DEBUG cachebuster: Matching "layouts/partials/main/meta.html" with source "assets/.*\\.(.*)$": no match

The class was added to hugo_stats.json but the style was not applied.

Yes that’s needed. Redid the config so now you have more options, but writeStats=true works.

See Configure Hugo | Hugo

To clarify, these are equivalent:

The new way (v0.115.1 and later)

[build.buildStats]
enable = true           # default is false
disableClasses = false  # default is false
disableIDs = false      # default is false
disableTags = false     # default is false

The old way…

[build]
writeStats = true       # default is false

I see…so I have the new way configured…but still I’m not sure why the styles are not being applied. The config code I shared before was copied from here when I began seeing this issue.

EDIT: This code seems to work. The utility classes are applied. I will test further and see.