Rebuilding my portfolio with Metalsmith

September 14th, 2017

Welcome to the first blog entry on my new portfolio website! I recently decided to rebuild my personal portfolio as a static website. My previous portfolio was built as a React single page application, which, to be fair, wasn't the ideal format for a simple portfolio website.

I actually loved using React, but I completely used it for the wrong purpose when building the site. While it was a great learning experience, there is no reason why my portfolio couldn't be a simple, static website.

I decided to see what's out there concerning static site generators these days. There is a plethora of options to choose from, but I decided on using Metalsmith, for a number of reasons.

First of all, Metalsmith's barebones-ness was probably the most attractive thing to me. There is no magic to Metalsmith. It reads files, runs them through a series of plugins, and finally outputs the results and writes them back to your filesystem. It's extremely simple, but also extremely powerful. There is no magic at work here - and it is a joy to work with.

Putting it all together

For my build process, I use a rather large amount of plugins. Without necessarily diving into the code, I think discussing each plugin, and the order they are used in, gives a great overview of how this site is generated.

function build() {
    Metalsmith(__dirname)
        .use(watch({ /* ... */ }))
        .use(readMore())
        .use(markdown({ /* ... */ }))
        .use(prism())
        .use(collections({ /* ... */ }))
        .use(permalinks({ /* ... */ }))
        .use(layouts({ /* ... */ }))
        .use(assets({ /* ... */ }))
        .use(purifyCSS({ /* ... */ }))
        .use(uglify({ /* ... */ }))
        .use(serve({  /* ... */ }))
        .build(err => {
            if (err) throw err;
        });
}

The watch and serve plugins take care of rebuilding files when any changes occur in the source directory, and serving them over a local HTTP server so I can view my website in any browser.

readMore is a custom plugin which splits up my blog posts written in Markdown to cut off text written after "READMORE" for the preview.

markdown converts Markdown and front matter into usable Javascript objects and HTML.

prism takes care of code syntax highlighting, using Prism.

collections bundles files with a special tags into iterable collections (like blog posts).

permalinks takes care of making links prettier.

layouts takes care of merging the HTML generated from Markdown with custom templates. I use Handlebars as a templating language.

assets simply copies my static assets (CSS files, images, Javascript files) over to the build directory.

purifyCSS removes unused styles from my CSS files, and merges them into one big stylesheet, using PurifyCSS.

uglify uses UglifyJS to minify my Javascript files.

Design

I made use of Spectre.css as a lightweight base CSS framework. I built my own styles on top of this framework, and heavily customized this base. I chose Spectre for its incredibly clean base styles, responsiveness out of the box, and lightweightness. Modifying the styles with SASS was a breeze. I have absolutely no complaints about Spectre, it was great for what I needed it for.

Hosting

After the build has been generated by Metalsmith, I need some place to host the files. I chose to use GitHub Pages for this purpose. GitHub Pages acts as a webhost for static websites that are hosted in a public GitHub repository. All you need to do is commit the built files to a GitHub repository, mark the repository as a GitHub Pages site, and you are pretty much done! It's incredibly simple, and best of all, it's completely free. This setup perfectly suited my needs, and it meant that my only cost was buying my own custom domain.