Pulling in static files from node_modules (bootstrap-icons)

I started a new client project today and I wanted to try using bootstrap-icons encapsulated directly in the project rather than via CDN.

Unfortunately, I have struggled trying to solve a “Hugo way” to lift the necessary files from node_modules into my Hugo pipeline. I have struggled with various incantations of [[modules.mounts]] and have not been able to figure it out yet.

The basic structure of the project:

I’ve created a very basic Hugo project and included bootstrap and bootstrap-icons via npm:

npm install --save bootstrap
npm install --save bootstrap-icons

I point to the bootstrap and include it in my Hugo pipeline via a couple of directives:

config.toml:

[module]
[[module.mounts]]
source = "assets"
target = "assets"

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

And in the html via the following:
head.html partial:

    {{ $options := (dict "targetPath" "css/styles.css" "outputStyle" "compressed") }}
    {{ $style := resources.Get "sass/main.scss" | toCSS  $options | minify }}
    <link rel="stylesheet" href="{{ $style.RelPermalink }}" media="screen">

(main.scss is in my assets/sass, and does the bootstrap scss inclusion from node_modules)

footer.html partial:

{{ $bootstrap := resources.Get "js/bootstrap.bundle.min.js" }}
{{ $js := slice $bootstrap | resources.Concat "js/bundle.js" | resources.Minify }}
<script src="{{$js.RelPermalink}}" defer></script>

This above all works flawlessly. I get a basic website with Bootstrap applied.

Now, I want to get the bootstrap-icons into the pipeline.

First, I need to update my assets/sass/main.scss to include the bootstrap-icons.scss:

@import "node_modules/bootstrap-icons/font/bootstrap-icons.scss";

A quick inspection of the bootstrap-icons.scss shows that it expects to be able to include the icon font from a local subdirectory:

$bootstrap-icons-font-src: url("./fonts/bootstrap-icons.woff2?524846017b983fc8ded9325d94ed40f3") format("woff2"),
url("./fonts/bootstrap-icons.woff?524846017b983fc8ded9325d94ed40f3") format("woff") !default;

And I thought I could solve this by doing the following mount:

[[module.mounts]]
source = "node_modules/bootstrap-icons/font/fonts/bootstrap-icons.woff"
target = "assets/sass/fonts/bootstrap-icons.woff"

[[module.mounts]]
source = "node_modules/bootstrap-icons/font/fonts/bootstrap-icons.woff2"
target = "assets/sass/fonts/bootstrap-icons.woff2"

And then … doing … something with resources.Get() … but I can’t find exactly what I am looking for in the docs.

So I am not quite there.

What I am trying to get happen is the have a copy of font files under node_modules land properly in the published destination (public/css/fonts) so that the compiled css file (public/css/styles.min.css) can properly @import the fonts.

1 Like

config.toml

[[module.mounts]]
source = "assets"
target = "assets"

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

[[module.mounts]]
source = "static"
target = "static"

[[module.mounts]]
source = "node_modules/bootstrap-icons/font/fonts"
target = "static/css/fonts"

assets/sass/main.scss

@import "node_modules/bootstrap/scss/bootstrap";
@import "node_modules/bootstrap-icons/font/bootstrap-icons.scss";
3 Likes

Just in case @jmoorings solution is not enough for you, I would go at this issue and set up with Webpack or a comparable “asset packing solution” that would do the copying for me while keeping the number of files to link to low (or at one).

I am already doing my own SCSS theme with adding bootstrap SCSS either by doing a ../../node_modules/bootstrap/scss/filename in my theme.scss (I did never got it working with options and a path to node_modules) and importing the JS as a module and build via JSBuild in Hugo.

So, depending on your Nerd-Level all is possible.

AHA! The secret sauce was actually

[[module.mounts]]
source = "static"
target = "static"

I had tried mounting into static before with exactly

[[module.mounts]]
source = "node_modules/bootstrap-icons/font/fonts"
target = "static/css/fonts"

but it had just blown away all my other static assets and I was <hands up in the air, ask now> at that point.

Thank you. (Now, I just wish I understood why you have to “remount” static to protect it from oblivion when doing this.)

Suppose, on a new site, you want to change your static directory from ‘static’ to ‘foo’.

[[module.mounts]]
source = "foo"
target = "static"

If we “protected” the original, this would not “change” the mount. It would add one.

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