Sacha Guddoy

Building a statically deployed blog using Netlify, Github, CircleCI and Contentful

Deployment strategies
Posted: Friday, August 2nd, 2019, 5:47:59 PM
Tags:
development
programming
javascript
meta
JAM

What is JAMstack?

JAMstack is a newish paradigm that can generally be thought of as aiming to allow for rapid iteration, high scalability and high performance by splitting each part of the web stack in to its own small service.

The key components of a JAMstack application... stack are the following:

  • Javascript

    • Fetches your data from API services

    • Facilitates UI functionality

  • API services

    • Fetch your data from external APIs

    • No need to run a web-server

  • Markup content

    • Can be statically generated at build-time

    • Or built at run-time

Advantages

Scalability

One of the biggest advantages of this application architecture is scalability. If you have too many users hitting your APIs several times every time they load a page, this could pose problems for scalability. Static exports flip that problem around, and inline the data at build-time rather than run-time. This means that users don't always need to hit your APIs to get content, and can just download static files from your CDN instead, a much cheaper, more scalable and faster solution.

Security

You can avoid exposing information about your api's structure and hide secure credentials by accessing APIs from your build system rather than in the browser.

Caveats

Complexity

This isn't a particularly straightforward thing to implement, even using a framework like next.js. There is a lot of a good tooling and some comprehensive templates for Gatsby which makes a stack like this easy to set up. However, without good knowledge of the underlying principles, how the tools implement them and how they fit together, it can be difficult to customise your implementation.

Furthermore there is a lot of fairly complex tooling involved, especially in the CI component of this stack. Too many hours have been lost debugging why something in my build that works on my workstation doesn't work in my CI environment.

This template's stack

This website is implemented using this paradigm. You can view the source code on GitHub.

I'm using NextJS for this deployment, and using its static export feature to build the markup.

Build

At build-time, we pull data from Contentful's API and inline it in to HTML files, which are then statically hosted on Netlify.

Within this getInitialProps call, I fetch content from the database and provide it as props to my page component.

export default class Blog extends React.Component {

  static async getInitialProps() {
    const data = await fetchSomeApiData();
    return { items: data.items };
  }
    
  render() {
    return <ul>{this.props.items.map(item => <li>item.title</li>)}</ul>;   
  }
}

NextJS will render the React components on the server using the data returned by getInitialProps, and inline the resulting HTML in the statically generated HTML file for that page.

When deployed, and a user loads the page in the client, all the markup is ready to be rendered before we need to download any Javascript at all, so our first "contentful" paint is extremely fast. Once this markup is loaded, the javascript bundles created by Next are downloaded and the React tree is mounted to the existing DOM structure.

We take a similar approach with the CSS. Using MaterialUI's makeStyles API, we can generate all the CSS we need at build-time and inline it in to the page.

Deploy

Deployment is handled by Netlify. By using Netlify's Github integration, we can listen for events on the repo like pushes to specific branches. When a pull request is made to master, we run the CI build and automatically deploy a preview version of the branch with Netlify.