
As a primarily back-end developer I tend to use Bootstrap in most of my full-stack applications. It's a great way to save some time getting a small project or prototype up and running. Using Bootstrap in Metalsmith isn't complicated, it just takes 3 plugins.
Project setup
This guide assumes some base understanding of Metalsmith, see "Starting a Metalsmith Project" on how to set up a basic project.

Starting a Metalsmith Project
Sep 19, 2019 · 12 min read
Metalsmith is a plugin-based static site generator originally from Segment. It's a current favorite of mine because of how sites are built as a pipeline of plugins where the output of each plugin is the input of the next. This allows for strong control over what happens and when it happens.
Installing packages
Starting with an empty project, install some Metalsmith plugins:
npm install --save metalsmith metalsmith-layouts jstransformer-handlebars metalsmith-markdown metalsmith-sass metalsmith-autoprefixer metalsmith-include-filesmetalsmith,metalsmith-layouts,jstransformer-handlebars,metalsmith-markdownas a base for our source parsing and templating.metalsmith-sassto compile the Bootstrap Sass which lets us customize its variables.metalsmith-autoprefixerto add vendor prefixes to CSS rules. The Bootstrap build also does this .metalsmith-include-filesto include external JavaScript in our source files.
And then install jQuery and Bootstrap :
npm install --save jquery bootstrapWe'll ignore the Popper.js peer dependency as we'll use the bundled Bootstrap JavaScript which includes it.
Source file structure
Create the following directories and files for use in the build pipeline:
.
├── index.js
├── layouts
│ └── page.hbs
└── src
├── index.md
└── static
└── css
└── bootstrap.scsslayouts/page.hbswill be our primary template formetalsmith-layoutsfor common elements like the navigation bar.src/static/css/bootstrap.scsswill be our primary Sass file that will optionally configure some variables before including Bootstrap.src/index.mdwill be our home page to processed throughmetalsmith-markdown.index.jswill be the Metalsmith build file.
Writing the source files
Now that we have all those plugins installed and files created let's start filling them in.
Metalsmith build file
Set up your index.js file like this:
const Metalsmith = require('metalsmith');
const sass = require('metalsmith-sass');
const autoprefixer = require('metalsmith-autoprefixer');
const include = require('metalsmith-include-files');
const markdown = require('metalsmith-markdown');
const layouts = require('metalsmith-layouts');
Metalsmith(__dirname)
.source('./src') // source directory for the pipeline
.use(sass()) // compile Sass
.use(autoprefixer()) // add vendor prefixes to CSS rules
.use(include({ // include external JavaScript
'static/js': [
'./node_modules/jquery/dist/jquery.slim.min.js',
'./node_modules/bootstrap/dist/js/bootstrap.bundle.min.js'
]
}))
.use(markdown()) // convert Markdown to HTML
.use(layouts({ // process all HTML files with Handlebars
pattern: '**/*.html',
default: 'page.hbs',
engine: 'handlebars'
}))
.destination('./build') // destination directory of the pipeline
.clean(true) // clean the destination directory before build
.build(function (err) { // execute the build
if (err) {
throw err;
}
});This will:
- Compile all
*.scssfiles withmetalsmith-sass. - Add vendor prefixes to CSS rules.
- Add the pre-built Bootstrap JavaScript and its dependencies as input files.
- Build
src/index.mdintobuild/index.htmlusinglayouts/page.hbsas the template.
Note the pattern configuration for metalsmith-layouts, without it our CSS and JavaScript files will also use the layout/page.hbs template.
HTML template
The Bootstrap team does a great job of providing many layout examples , so to keep this simple we'll use the "Starter Template ."
Fill in your layouts/page.hbs like this:
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{{ title }}</title>
<link href="static/css/bootstrap.css" rel="stylesheet">
</head>
<body cz-shortcut-listen="true">
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="http://example.com" id="dropdown01" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown01">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
<main role="main" class="container">
{{{ contents }}}
</main>
<script src="static/js/jquery.slim.min.js"></script>
<script src="static/js/bootstrap.bundle.min.js"></script>
</body>
</html>Things to note are:
- The local
<link>and<script>sources, they will end up in ourbuild/directory thanks tometalsmith-sassandmetalsmith-include-files. - The
{{ title }}placeholder to be replaced with the frontmatter from anysrc/*.mdfiles. - The
{{{ contents }}}placeholder to be replaced with the contents of anysrc/*.mdfiles.
Index page
Continuing to use the example content from the "Starter Template " example, fill src/index.md in with:
---
title: Starter Template for Bootstrap
---
# Bootstrap starter template
Use this document as a way to quickly start any new project.
All you get is this text and a mostly barebones HTML document.Primary Sass file
To start, fill out src/static/css/bootstrap.scss with only:
@import '../../../node_modules/bootstrap/scss/bootstrap';That will get the stock Bootstrap building.
But the value of using metalsmith-sass to compile the Bootstrap Sass instead of using the pre-built CSS is we can customize various variables. If we wanted to change the primary color from blue to something else all we have to do is write:
$primary: darkorange;
@import '../../../node_modules/bootstrap/scss/bootstrap';Refer to the official documentation on available variables and how they work.
From here we can also add some custom CSS after all the Bootstrap rules:
$primary: darkorange;
@import '../../../node_modules/bootstrap/scss/bootstrap';
body {
background: darkgray;
}Conclusion
With using just 2 Metalsmith plugins we're able to customize and build the Bootstrap CSS from source and include the pre-built Bootstrap JavaScript in our input files.

