Including assets within a Hugo module

I have created a Hugo theme component module, and gotten it successfully setup and working in a theme. Layouts (in this case a shortcode) are being pulled in just fine.

But I also have some asset files: assets/js/script.js and assets/scss/styles.scss. I can’t figure out how or where I’m supposed to configure those, as this is my module’s config.toml and they don’t seem to be getting included:

[module]
  [module.hugoVersion]
    min = "0.85.0"
    extended = true
  [[module.mounts]]
    source = "assets"
    target = "assets"
  [[module.mounts]]
    source = "layouts"
    target = "layouts"

When I pull the module in and run hugo mod vendor, I can see that both the assets directory and the layouts directory are being included, and again the shortcode works so I know layouts is there.

But how do I – either in the module or within the theme that I’m using the module – tell Hugo to include those assets in the theme?

And in Hugo extended will they be incorporated into a single JS and a single CSS file with the theme’s assets, or do they get inserted as additional <script>/<link> elements?

I’ve searched the forum and the web quite a bit but most of the guides on Hugo modules are reasonably enough focused on using modules, not developing them. If you know of guides on that aspect in particular please let me know.

Thanks!

The short answer is that you need to use it or build it.

Both of your uses (JS and SCSS) has similar but slightly different answers, so I’ll take the first one:

See js.Build | Hugo

E.g.:

{{ $js := resources.Get "js/script.js" | js.Build  }}
<script type="text/javascript" src="{{ $js.RelPermalink }}" defer></script>

If you include the above in your HTML head section, it should do its thing. There are more details to it than that, but that’s a start.

For SCSS, see https://gohugo.io/hugo-pipes/scss-sass/#readout

So just to clarify, if I’m developing a Hugo module, I have to tell people who are using that module to call the asset files in their templates?

I thought for sure I had seen Hugo modules that involved JS and/or CSS/Sass where the instructions were simply to add the module using hugo mod get and list it in the module imports with path. I’ll see if I can find some examples of those modules.

OK, I found some examples of these kinds of modules:

That last one tipped me off to what’s going on: They’re calling their assets in their partials.

For CSS I guess that’s OK if it renders it in <style> tags and it’s not too long, it wouldn’t slow down page rendering although it might increase effective specificity in ways that make it hard for the end-user to override.

But for JS that’s really unfortunate – it means render-blocking calls to a JS file gets loaded partway into pageload.

I wish there was some function in Hugo that would allow partials/modules to “hoist” (for lack of a better term) CSS up into the <head> and JS down into just before </body>. Would something like that be considered as a future feature? Or is there some different way of architecting things that would achieve that?

1 Like

@iaeiou was working on assets (specifically styles in their case, I believe) as part of shortcodes or partials that end up in the right place without duplication.

There are also methods of making CSS page-specific, which @bwintx wrote about

2 Likes

By adding “defer” to the scrip tag you can avoid that.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer

2 Likes

@cshoredaniel Using Scratch to track whether a file has already been included is a great idea, thanks for suggesting that. (Scoped styling was also interesting, but ultimately it looks like he abandoned it. Hopefully native CSS @-scoping will be finalized and browser-supported soon…)

@frjo You’re right – and I see now that @bep included that in his suggestion.

Are there any plans/interest in including assets, at least in the context of a shortcode Hugo module? If not, would there be interest in documenting the Scratch use from @iaeiou as a best practice? I think more could be done to build up the Hugo module ecosystem and this could be one part.

1 Like