An opinionated boilerplate template for creating a statically-generated site, using content managed in Contentful, with a build system backed by Metalsmith.
The build system builds a static site to the /build
folder, which can be deployed on your static host of choice. It's geared towards use on Netlify, but you can serve the files from any host that serves static content, including GitHub Pages.
This is still pretty new, so we're still working out some kinks, however we're using it on a number of production sites and it's been very robust.
Node.js 4+ (developed against v6.2 so YMMV). You're using nvm
right? Great — the repo is initialized with an .nvmrc
file so run nvm use
and you should be golden
# clone the repo
git clone https://github.com/centre-for-effective-altruism/contentful-metalsmith-boilerplate your_project_name
cd your_project_name
# optional — remove the original repo's commit history so you're starting with a blank slate. BE CAREFUL WITH rm -rf!!!
rm -rf .git
# create a new repo on github, and add it as your 'origin' remote
git remote add origin https://github.com/yourhandle/your_project_name
# if you want to update your clone as new commits are made to the original repo, add the original repo as the 'upstream' remote
git remote add upstream https://github.com/centre-for-effective-altruism/contentful-metalsmith-boilerplate
# install packages
npm install
Link the build system to Contentful by adding API keys to a .env
file
- Create a new, empty Contentful space
- go to the APIs tab and generate a new set of keys (or just use the default ones)
- The Content Management API key is not available from the regular APIs tab; instead, open the link to the Content Management API page in a new tab, which should give you a key you can use. You could also create a new App and generate an OAuth Token and use that instead...
- use the command line tools (see below) to add your environment variables:
npm run tools
# ? What do you want to do? (Use arrow keys)
# ...
# ❯ Create an Environment Variables file (.env)
(Sensitive data like API keys should never be checked into source control. The .env
file is excluded by .gitignore
, so you should be fine, but you should be aware that that's where this data is being stored so you don't inadvertently check it in...)
To get started, it's a good idea to populate your Contentful Space with default Content Types and some Entries
Add default Content Types:
npm run tools
# ? What do you want to do? (Use arrow keys)
# ...
# ❯ Create default Content Types
Add default content:
npm run tools
# ? What do you want to do? (Use arrow keys)
# ...
# ❯ Add default content to space
If you don't want to use the default Content Types and content, start from scratch.
Add a new Content Type:
npm run tools
# ? What do you want to do? (Use arrow keys)
# ...
# ❯ Create new Content Type
Then go to Contentful and add a few entries.
Once you've got the site installed, you just have to build it!
npm run build
# builds static site to /build
(This command bundles scripts with Browserify, compiles SCSS partials into a single CSS file, then runs the Metalsmith build (see Build commands below for info on running these commands individually)
The static site is just a collection of HTML files, so any simple web server will do. We just use http-server
:
npm install -g http-server
- Open a new Terminal tab
- Run
cd /build
(i.e. the build directory) - Run
http-server
(serves files at http://localhost:8080 by default)
Open up a browser and look at what you've done!
npm run build
— build everything (by default in development
mode)
npm run scripts
— just rebuild styles
npm run styles
— just rebuild scripts
npm run metalsmith
— rebuild static site using Metalsmith, skip rebuilding styles/scripts
npm run staging
- run the build in staging
mode (essentially the same as production
but with more debugging). Alias for NODE_ENV=staging npm run build
npm run production
- run the build in production
mode (enables minification, file concatenation, CSS purification). Alias for NODE_ENV=production npm run build
To access the tools, run:
npm run tools
This will give you several options:
? What do you want to do? (Use arrow keys)
❯ Create new Metalsmith plugin
Create new Content Type
Delete Content Types
──────────────
Create default Content Types
Add default content to space
──────────────
Create an Environment Variables file (.env)
Creates a file with Metalsmith plugin boilerplate under lib/metalsmith/plugins
, and will helpfully print a require
call to the REPL that you can add to the main metalsmith.js
task file (located in tasks/metalsmith
).
Remember to also add the .use()
call to the Metalsmith build where you want your plugin to appear:
const insertEmojiRandomly = require(paths.lib('metalsmith/plugins/insert-emoji-randomly'))
...
metalsmith
.source('../src/metalsmith')
.destination('../build')
...
.use(insertEmojiRandomly())
(remember to actually call the plugin, and not just pass in the variable — the plugin boilerplate returns a function, so use(myPlugin)
won't work, you'll need .use(myPlugin())
)
The plugin boilerplate adds an options argument, which you can use to easily filter the type of files that will be passed to the plugin (using minimatch glob patterns)
const defaults = {
// set some default options here
filter: '**/*.html'
}
Uses the Contentful Content Management API to create a new Content Type in your Contentful Space, and adds the necessary local data to the build system to make sure that Entries will be included in the build. (If you want to hack around with these files, look in tasks/metalsmith/content-types
)
Setting the apperance of Contentful field types (like setting a Short Text field to Slug
or a List field to Radio
) is not possible over the API, so you'll need to do it manually throught the Contentful web interface.
If you've got a Content Type on Contentful you don't need any more, remove it using this command (which also removes local build files). This is a non-undoable, destructive action, so use this carefully!
Most sites use the same few basic Content Types over and over again. If you want to get up and running quickly, you can use this tool to add some defaults to Contentful. This runs the same script as Create new Content Type
under the hood, so will add the necessary local info to add each Content Type to the Metalsmith build.
The Content Types are:
Page
- static pagesPost
- regularly updated content like a blog postLink
- a link to internal or external content. Useful if you want to have multiple Links in a Series (e.g. an external link in your navigation menu etc)Series
- It's often useful to be able to group content into an ordered series, and this is easy with Contentful's powerful relational model. For example, the default navigation menu is aSeries
containing a list ofPages
andLinks
The default Content Types are all pretty basic, but are great for getting started. You can then run Add default content to Space
(see below) to populate the site with some dummy content
Assuming you've added the default Content Types (as above), you might also want to add some dummy content to see how the boilerplate works. It's also a good place to start if you want to repurpose some of it (e.g. it will create a Main Navigation Menu Series
which you can reuse with your own pages)
We love using Netlify to serve our static sites. It's really simple to set up a new site, and they handle continuous integration by linking to your Github repo.
Once you've created a new site and linked your repo, you'll need to tell Netlify how to build your site. This just means adding the build command and setting environment vars:
Branch - probably master
(the default), unless you're committing production code to a different branch
Dir - build
(default)
Build command - npm run build
You can add environment vars on the Advanced Settings tab. The ones you want are:
NODE_ENV
=> production
CONTENTFUL_SPACE
=> your_contentful_space_id
CONTENTFUL_DELIVERY_ACCESS_TOKEN
=> your_contentful_delivery_access_token
(If you've already got the site building and you're happy re-using the same API key in development and production, you can copy these values from your .env
file. Otherwise generate a new API key in Contentful and copy the details from there. You won't be using the management tools on the server, so you won't need Contentful Preview or Management API keys)
That's it! Click 'build your site', wait for the site to build/deploy, and bask in the warm glow of how easy that all was.