Using `hugo_stats` extractor for Tailwind 3?

Now that Tailwind is in full JIT mode, the purge config is replaced by a content config. This way Tailwind can watch your layouts and generated the necessary classes.

It would be ideal to have it read the hugo_stats.json file but I can’t find a way.

Previously with Tailwind 2: under the purge key of `tailwind.config.js``

content: [
    './hugo_stats.json',
    './functions/.html',
    './layouts/**/*.html',
  ],
  extractors: [
    {
      extractor: (content) => {
        let els = JSON.parse(content).htmlElements;
        return els.tags.concat(els.classes, els.ids);
      },
      extensions: ['json']
    },
  ],

Now with Tailwind 3, following the doc I tried the following:

files: [
  './hugo_stats.json',
  './layouts/**/*.html',
],
extract: {
  'json': (content) => {
    let els = JSON.parse(content).htmlElements;
    return els.tags.concat(els.classes, els.ids);
  }
}

But I end up with a SyntaxError: Unexpected end of JSON input error.

Anybody managed to achieve this?

Do you really need a custom extractor? Because I don’t use it and it works just fine with v3 and the generated hugo_stats.json file.

On my setup, Tailwind does not read the hugo_stats.json content:

  {{ $class := print "bg-blue" "-800" }}
  <div class="{{ $class }}">
    Hello
  </div>

bg-blue-800 is not added.

I am obviously missing something. What’s the advantage of doing that? Why not just:

<div class="bg-blue-800">

I also don’t use hugo_stats.

It was just an example, a poor one I must admit. Conditioning the “800” to some external params etc…
This one’s better:

 {{ $class := print "bg-blue-" (cond .Params.dark "800" "400") }}
  <div class="{{ $class }}">
    Hello
  </div>

Gotcha! That makes sense.

Personally, after far too many occasions wondering why styles aren’t present in production environments, I avoid string concatentation for classes altogether now even though I’m now using Tailwind 3 in JIT mode, so it’ no longer an issue anyway.

Only thing I can think of is that maybe your postcss process is running before hugo_stats is written to disk?

You need to use PostProcess

Have you been able to make the custom extractor work for hugo_stats.json? If so, how? Thanks.

There’s a working example with Tailwind 3 and hugo_stats here:

Thanks. I’m using that, but unfortunately it’s not 100% working this way. More complicated rules like [&:checked~header_nav]:bg-red-100 are ignored. Therefore my search for an alternative approach.

But I’m starting to think it’s a ultimately a Tailwind issue, as I can’t get such rules to be picked up with a custom extractor as well.

I’ve finally seem to have figured out how the extractor works (line oriented) and found the issue: Hugo uses unicode notation for the & in the selector, but Tailwind doesn’t like it.

This configuration works for me:

tailwind.config.js

module.exports = {
  content: {
    files: ["./hugo_stats.json"],
    extract: {
      json: (line) => {
        const match = /^"(.*)",?$/g.exec(line);
        if (match) {
          return match[1].replace('\\u0026', '&').match(".*");
        }
        return [];
      }
    }
  },
};

I think you need to be pragmatic about this and put any special stuff in a whitelist setup in your Tailwind config.

For me, that would be the least practical. Too much mental load. Even more so for the next guy. Better to fall back to writing css directly in a separate file.

But both approaches defeat one of the selling points of Tailwind where everything related should be accessible in one place (granted sometimes there can be a bit bloat this way).

Anyway, thanks for caring. Awesome job with Hugo. Love it!

If you write rules like [&:checked~header_nav]:bg-red-100 a lot, then sure.

I have worked with some largish Tailwind 3.x sites using the hugo_stats.json as the main source of truth, and with just a handful of whitelist additions it works reallly well.

But up to you.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.