Customizing Bootstrap 4 with Hugo pipes
Overview
We will use npm
to handle Bootstrap package, it will make it easy to
keep up to date with their releases.
Prerequisites
To make Hugo compile SASS files you need the extended version. As of Hugo version 0.43, Hugo releases two binary types, the extended version makes it possible to edit SCSS files.
If you try to compile SASS files with the regular version you will get the following error message:
$ hugo
Building sites β¦ ERROR 2018/08/06 20:32:24 error: failed to transform resource: TOCSS: failed to transform "sass/main.scss" (text/x-sc
ss): this feature is not available in your current Hugo version
Install dependencies
Create a package.json
file with your npm
dependencies running npm init .
:
$ npm init .
Install projects with npm install bootstrap jquery popper.js postcss-cli autoprefixer --save
:
$ npm install bootstrap --save npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN bootstrap@4.1.3 requires a peer of jquery@1.9.1 - 3 but none is installed. You must install peer dependencies yourself. npm WARN bootstrap@4.1.3 requires a peer of popper.js@^1.14.3 but none is installed. You must install peer dependencies yourself. + bootstrap@4.1.3 added 1 package in 2.58s $ npm install jquery --save npm WARN bootstrap@4.1.3 requires a peer of popper.js@^1.14.3 but none is installed. You must install peer dependencies yourself. + jquery@3.3.1 added 1 package in 1.266s $ npm install popper.js --save + popper.js@1.14.4 added 1 package in 14.954s $ npm install postcss-cli autoprefixer --save npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) + postcss-cli@6.0.0 + autoprefixer@9.1.0 added 255 packages in 20.39s
Ok, no more warning ;)
Now we have all Bootstrap SASS files at
node_modules/bootstrap/scss/
.
Theory
SASS files
We need to create a resource from an asset SASS file so we can load it and use Hugo pipes.
Basic Sass processing in Hugo
Sass files in Hugo should be located under the /assets
folder.
It can go into the theme’s folder, or project’s root folder, (the latter one enables you to customize an existing theme too).
Create the directory assets/sass
mkdir -p assets/sass
Then the assets/sass/main.scss
file will contain our customized variables.
Put some example content there to try to load it in Hugo.
For example, in /assets/sass/main.scss
:
$not-so-white: #ffe;
body {
background-color: $not-so-white;
}
Process Sass file from templates
In the head.html
partial, we will load the above SASS file with
resources.Get
.
The most basic way to load the Sass file without any further processing is:
{{ $style := resources.Get "sass/main.scss" | toCSS }}
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
Go and try to build your site checking that there is a main.css
file
with the processed content:
$ hugo $ cat public/sass/main.css body { background-color: #ffe; }
Possible transformations
You can also use the following transformation options in your pipes:
resources.PostCSS
orpostCSS
: Process your CSS with PostCSS. Config file support (project or theme or passed as an option).resources.Minify
orminify
: Currently supports css, js, json, html, svg, xml.resources.Fingerprint
orfingerprint
: Creates a fingerprinted version of the given Resource with Subresource Integrity.resources.Concat
orconcat
: Concatenates a list of Resource objects.resources.ToCSS
ortoCSS
: Compile SCSS or SASS into CSS.- also accepts SASS directives in a
dict
.
- also accepts SASS directives in a
For example, putting all of the above together:
{{ $options := (dict "targetPath" "css/style.css" "outputStyle" "compressed" "enableSourceMap" true "includePaths" (slice "themes/simpleit/node_modules")) }}
{{ $style := resources.Get "sass/main.scss" | toCSS $options | postCSS | minify | fingerprint }}
<link rel="stylesheet" href="{{ $style.RelPermalink }}" >
$ hugo $ cat public/css/style.css body{background-color:#ffe} /*# sourceMappingURL=style.css.map */
css/style.css
as set in the targetPath
options dictionary key.Customizing Styles
Having understood how basic SASS processing in Hugo works, now we focus on customizing Bootstrap.
To customize website styles I want to achieve two goals:
- customize the variables that Bootstrap uses in their own SASS files
- use some of those SASS variables in my website SASS files
To achieve this we will create three files:
assets/sass/main.scss
: the main SASS file that import other SASS files in the right order.assets/sass/custom_variables.scss
: the customized Bootstrap variables.assets/sass/styles.scss
: main website styles with all Bootstrap variables available (customized and non-customized).
Custom Bootstrap variables
In assets/sass/main.scss
we load the custom variables, then the rest
of the Bootstrap styles and finally we load our custom website styles:
@import "custom_variables";
@import "../../node_modules/bootstrap/scss/bootstrap";
@import "styles.scss"
So to customize Bootstrap we need to copy any variable from
node_modules/bootstrap/scss/_variables.scss
into our own
assets/sass/custom_variables.scss
.
If we are importing full Bootstrap SCSS after customizing its
variables, why do they won’t get replaced? This is because the
!default
directive.
Every Sass variable in Bootstrap 4 includes the !default flag allowing you to override the variableβs default value in your own Sass without modifying Bootstrapβs source code. Copy and paste variables as needed, modify their values, and remove the !default flag. If a variable has already been assigned, then it wonβt be re-assigned by the default values in Bootstrap.
Example
Let’s make Bootstrap use some stylish serif fonts instead of sans-serif.
In assets/sass/custom_variables.scss
create the
$font-family-serif
variable and replace Bootstrap’s $font-family-base
:
$font-family-serif: Lucida Bright, Lucida Fax, Palatino, "Palatino Linotype", Palladio, "URW Palladio", serif;
$font-family-base: $font-family-serif !default;
Use Bootstrap variables in our styles
All the Bootstrap variables are available in our
assets/sass/styles.scss
file.
Example
body {
font-size: $font-size-lg * 2;
}
$ cat public/css/styles.css
/*!
* Bootstrap v4.1.3 (https://getbootstrap.com/)
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/:root{--blue: #007bff;
...
body{font-size:3.08rem}
/*# sourceMappingURL=style.css.map */
Add javascript
Lastly, add required Javascript files:
Copy the required javascript files to assets/js/vendor
. Here is a
simple Make recipe:
ASSETS_DIR := assets/js/vendor/
build-js:
mkdir -p $(ASSETS_DIR)
cp node_modules/jquery/dist/jquery.min.js $(ASSETS_DIR)
cp node_modules/popper.js/dist/umd/popper.min.js $(ASSETS_DIR)
cp node_modules/bootstrap/dist/js/bootstrap.min.js $(ASSETS_DIR)
Run make build-js to copy them to the assets location.
Now include them in your template before the closing </body>
HTML tag:
{{ $jquery := resources.Get "js/vendor/jquery.min.js" }}
{{ $popperjs := resources.Get "js/vendor/popper.min.js" }}
{{ $bootstrap := resources.Get "js/vendor/bootstrap.min.js" }}
{{ $js := slice $jquery $popperjs $bootstrap | resources.Concat "js/bundle.js" | resources.Minify }}
<script src="{{$js.RelPermalink}}"></script>
gitignore
Keep your repo clean, add to .gitignore
:
vendor/
resources/
/node_modules
Final tree structure:
.
βββ node_modules/
β βββ bootstrap
β βββ jquery
β βββ popper.js
ββ assets/
βββ js
βΒ Β βββ vendor
βΒ Β βββ bootstrap.min.js
βΒ Β βββ jquery.min.js
βΒ Β βββ popper.min.js
βββ sass
βββ custom_variables.scss
βββ main.scss
βββ styles.scss
Then our styles file style.css
would be minified and looking
something like: public/style/style.min.d58f8b04f38cc0130246ca80fac07c79f453344c800db4f815543d84a8bc4bf2.css
at the final site.
Repos
There is a Github repo available that shows a hugo site with all these steps applied at: https://github.com/marcanuy/hugo-pipes-bootstrap
This approach it is also used by Hugo’s theme SimpleIT Hugo Theme (it will look familiar, this website is built with it ;)
References
- https://github.com/gohugoio/hugo/releases
- https://getbootstrap.com/docs/4.1/getting-started/theming/
- https://gohugo.io/hugo-pipes/
- Have Different Portions Of Code For Production And DevelopmentAugust 14, 2018
- Deploying a Hugo website to AWS in 6 steps (CDN+HTTPS)August 12, 2018
- Customizing Bootstrap 4 with Hugo pipes
- A first approach to Hugo for Jekyll developersAugust 4, 2018
- How I migrated this website articles from Jekyll to HugoAugust 4, 2018
- Hugo overview and basic conceptsOctober 10, 2017
Articles
Except as otherwise noted, the content of this page is licensed under CC BY-NC-ND 4.0 . Terms and Policy.
Powered by SimpleIT Hugo Theme
·