Create Static Sites With Webpack
Tags: webpack, static, building, bundling
Published: 2017-02-17 11:30:00

---
title: Create Static Sites With Webpack
published: true
description: Creating static sites with Webpack's static site generator plugin.
cover_image: 
tags: webpack, static, building, bundling, JAMstack
---
_TL;DR Here is a [repository](https://github.com/kay-is/webpack-static-plugin-example) with a working example. :)_

## Why?

Static sites can be easily stored by content delivery networks, which have servers right besides your users. Since latency (and not bandwidth) is the big problem of the Web, or the Internet in general, you want to store your content as near to your users as possible.

See: [JAMstack](https://jamstack.org/) && [High Performance Browser Networking](http://chimera.labs.oreilly.com/books/1230000000545)

## But Why Webpack?

Webpack has a nice small plugin called [static site generator webpack plugin](https://github.com/markdalgleish/static-site-generator-webpack-plugin) which allows you to run bundled code on _build time_ to generate static HTML pages. Also it can build your regular client code in the same step.

This allows you to pre-render things and do your well known single page application thing with one tool.

## How?

If you know how you create multiple entry points in Webpack, you almost got it. The plugin _runs_ one entry point after it has been built locally.

Here I create one for _regular_ SPA building and one that should be used to render our static pages:

    entry: {
      main: './src/client.js',
      static: './src/static.js',
    }

Also, the plugin needs a route array and will use every entry in it to run _through_ the static code, passing the route of the current run into your script. Additionally, a reference to extra data can be passed.

If you add your routes to your extra data you can use this in your script later.

    const data = {
      routes: [
        {url: '/', title: 'Home'},
        {url: '/about', title: 'About'},
      ]
    }

In our example the creation of the plugin would look like that:

    const static = new StaticSiteGeneratorPlugin(
      'static',
      data.routes.map(r => r.url),
      data
    )

The name of the entry point to use, an array of URLs and some extra data.

Since the _static_ bundle will be run on your local Node.js, you have to set your output to UMD.

    output: {
      filename: '[name].js',
      path: 'build',
      libraryTarget: 'umd',
    },

Your `static` entry script now needs to export a function that will get your `data` reference as argument, this `data` will have an extra attribute called `path` that will change for every run. In our example there will be 2 runs, in the first `path` will be `'/'` in the second it will be `'/about'`.

    module.exports = data =>
      `<h1>${data.routes.find(r => r.url == data.path).title}</h1>`

Your function can be synchronous, like here or return a `Promise` that resolves to your HTML string, in case you need to gather some asynchronous data.

The `data.path` can be used to render different files for every run and you can import your other bundles, `main` in this example, via a `<script>` it your HTML to add the usual client side JavaScript as your know it.

## Conclusion

Webpack offers you a simple way to create static pages with the render of your choice and integrates them nicely with the client side JavaScript. This allows to build [JAMstack](https://jamstack.org/) like applications without much tooling.