Hugo package management - import and include upstream CSS and JS in Hugo

Automatically add JQuery, Font Awesome and Bootstrap using NPM

Posted on 29 December 2019

Generally, there are 2 main options to include JS and CSS in Hugo, one is to use CDN and other is to manually download external dependencies and version control them into your own project. Personally, I like the idea of managing upstream dependencies automatically using a package manager.

You can manage dependencies in Hugo however you like - Hugo is flexible enough to work with your workflow.

Why bother serving external JS & CSS when you can CDN?

There are times when speed and Bandwidth optimisation is key success criteria. So, instead of relying on CDNs to serve JS & CSS, you may want to optimise your JS & CSS before serving it out. There are other instances where you want to include SCSS from upstream package like bootstrap into your own theme. This tutorial is all about how to go about doing this and isnt about merits of each approach.

So, here a quick summary of how my dependencies are managed, updated and imported automatically using Hugo.

  • NPM manages the dependencies
  • External dependencies are mapped to Hugo assets directory
  • Dependencies are now available natively to Hugo for any CSS/JS processing and pipelines workflows.

Lets deep dive..

NPM to the rescue for Package management.

Define your dependency packages as you would do with any NPM project. Here is what my package.json looks like:

"dependencies": {
    "@fortawesome/fontawesome-free": "5.10.2",
    "bootstrap": "4.3.1",
    "jquery": "3.4.1"
}

Mount node_modules folder to Hugo

By default Hugo will only process CSS and JS files in the assets folder. So we have to mount node_modules folder to assets/

In your config.toml file, define your mount points.. Mine look like this..

[module]
  [[module.mounts]]
    source = "./node_modules/bootstrap/scss/"
    target = "assets/scss/bootstrap"

  [[module.mounts]]
    source = "./node_modules/@fortawesome/fontawesome-free/scss"
    target = "assets/scss/fontawesome"

  [[module.mounts]]
    source = "./node_modules/@fortawesome/fontawesome-free/webfonts"
    target = "static/webfonts"

  [[module.mounts]]
    source = "./node_modules/jquery/dist"
    target = "assets/js/jquery"

  [[module.mounts]]
    source = "./node_modules/bootstrap/dist/js"
    target = "assets/js/bootstrap"    

Every dependency package is now available into the Hugo folder system.

How to make use of them..

Use as you would normally.. here is an example of how to import external SCSS into your own theme:

// Import Bootstrap
@import "./bootstrap/bootstrap.scss";

// Import fontawesome
@import "./fontawesome/fontawesome.scss";
@import "./fontawesome/brands.scss";
@import "./fontawesome/regular.scss";
@import "./fontawesome/solid.scss";

In the above example, the complete folder path would be:

Original path is:

root/node_modules/bootstrap/scss/bootstrap.scss

and its mounted to:

root/themes/mytheme/assets/scss/bootstrap/bootstrap.scss

Conclusion

You and now update your external packages using your normal NPM flow. Hugo is awesome and flexible enough to work with any of the choices you make, however good or bad they might be.