Building a serverless static website in 2020

The new decade is upon us, and it's time to leave simple server-bound websites behind. We now have the tools and infrastructure available to build incredibly fast, maintainable, and dynamic experiences without relying on traditional server-side content management systems.

Serverless? Static? What?

If you're used to working with a CMS like Wordpress, building a decoupled, statically generated website might take a small paradigm shift. A typical website can be spit up into 3 parts:

  1. Content — creating and updating pages, posts, etc
  2. Codebase — taking data and building pages from it
  3. Serving — how pages get to the user when they visit your site

In a traditional setup, the CMS handles every piece of this puzzle. You build a theme to define how pages/posts/etc look, there's some kind of admin area where authors can manage content, and you setup a server that takes your content and your theme, compiles a page, and then sends it down the wire every time a user visits your site.

In a serverless setup, each of these pieces are handled by dedicated tools that are best suited to the job. Your codebase is built with a static site generator, which takes content and precompiles your entire site. You manage content with a headless CMS, which exposes powerful and flexible APIs to access content. And since there's no server required to compile page requests, you can serve your whole site on blazing fast static CDNs.

It may sound like more effort than letting a traditional CMS handle everything, but in practice building a decoupled, serverless website saves development time, dramatically improves performance and security, and is effortlessly maintainable and scalable.

Going serverless with Gatsby and Prismic

While there are many static site generators, and just as many headless CMSs, we're going to focus on two of the market leaders — Gatsby and Prismic.

Gatsby: Not your mama's website generator

Gatsby has ushered in a small revolution in static site generators. It couples the modular design ethos of React for building pages, with a powerful and flexible data layer built on top of GraphQL.

The GraphQL data layer is backend agnostic, using data 'sources' for a plethora of content providers. Which means that you can use whatever CMS you like (even Wordpress!) and still take full advantage of Gatsby's React framework.

Building in React not only encourages a highly maintainable component-centric workflow, it also results in a fantastic end-user experience. Gatsby prerenders your site in a build step, and then “rehydrates” React once a user has visited the page. Which means that the site is loaded as fast as static HTML, but once a user starts interacting with it they get an app-like experience, with instant page changes that don't require a refresh.

Prismic: Making CMSs fun again

Prismic is a headless CMS which provides a powerful GraphQL API for accessing your content. Rather than 'posts' or 'pages', in Prismic you create completely custom content types to suit your needs. You can create single pages (eg: home page), or repeatable collections (eg: posts). These types can have any number of different content fields, from Wordpress-like rich text, to images, embeds, and repeatable groups.

While there are many headless CMSs that all share the same basic approach and features, Prismic stands apart with Content Slices. These allow you to define content 'modules', that can be inserted into a page and reordered, allowing you to create powerful art-directed pages without additional code. Check out our deep-dive on creating branded case studies with Prismic slices for more.

Getting started

The easiest way to get started with Gatsby is by using the Gatsby CLI to scaffold a new site.

# Install the CLI
npm i -g gatsby-cli
 
# Create a new site
gatsby new gatsby-site

Then run gatsby develop in your site folder to start a hot-reloading development environment, available on http://localhost:8000. The files in src/pages are compiled into the pages of your site, and you can programatically generate pages from data as well (we'll touch on this soon). Check out the Gatbsy tutorial for a more thorough overview on getting up to speed with Gatsby.

Setup Prismic

Head to the Prismic website and create a new repository. Take note of the repository name, and then install a data source for Prismic in Gatsby. We recommend gatsby-source-prismic-graphql.

Install the data source and some Prismic helpers:

npm i gatsby-source-prismic-graphql prismic-reactjs

Configure the data source in your gastby-config.js:

{
  resolve: `gatsby-source-prismic-graphql`,
  options: {
    repositoryName: 'YOUR-PRISMIC-REPO'
  }
}

Then setup a link resolver for Prismic's rich text fields in your gatsby-browser.js:

src/utils/linkResolver.js
exports.linkResolver = function linkResolver(doc) {
  // Route for blog posts
  if (doc.type === 'post') {
    return '/blog/' + doc.uid;
  }
  // Homepage route fallback
  return '/';
};
gatsby-browser.js
const { registerLinkResolver } = require('gatsby-source-prismic-graphql');
const { linkResolver } = require('./src/utils/linkResolver');
 
registerLinkResolver(linkResolver);

Fetch content from Prismic

You can now use GraphQL to fetch content for your pages from Prismic. All your content will be available under the prismic node in your site's data tree

import React from 'react';
import { graphql } from 'gatsby';
import { RichText } from 'prismic-reactjs';
 
export const query = graphql`
  {
    prismic {
      page(uid:"homepage", lang:"en-us") {
        title
        description
      }
    }
  }
`
 
export default function Page({ data }) => (
  <>
    <h1>{RichText.render(data.prismic.title)}</h1>
    <h2>{RichText.render(data.prismic.description)}</h2>
  </>
);

The easiest way to build queries is by using the GraphiQL interface bundled with Gatsby, access it by running gatsby develop and then opening http://localhost:8000/\_\_\_graphql.

Generate pages

If you have pages that are repeatable content types (eg: blog articles, case studies, etc), then you'll need to use Gatsby to programatically generate them from the data in Prismic. Luckily gatsby-source-prismic-graphql comes with a handy page generation helper.

Configure new generated pages in your gatsby-config.js:

{
  resolve: 'gatsby-source-prismic-graphql',
  options: {
    repositoryName: 'gatsby-source-prismic-test-site', // (required)
    pages: [{
      type: 'Article',         // TypeName from prismic
      match: '/article/:uid',  // Pages will be generated under this pattern (optional)
      path: '/article',        // Placeholder page for unpublished documents
      component: require.resolve('./src/templates/article.js'),
    }],
  }
}

Deploy your site

Compile your site by running gatsby build, and you're ready to deploy it. We highly recommend taking advantage of the fact that your website is now static HTML and JavaScript, and hosting it on a static CDN. This will result in the highest possible performance and security for your visitors.

There are many CDNs available, but we recommend using Netlify. They are tailored to the serverless workflow, allowing you to deploy directly from popular code hosting services like Github and Bitbucket.

Make sure your site has a valid package.json with an NPM build script.

{
  "name": "my-site",
  "version": "0.1.0",
  "scripts": {
    "develop": "gatsby develop",
    "build": "gatsby build"
  }
  /* ... */
}

Then create a git repository and push your code to Github or Bitbucket. Setup a new project on Netlify, connecting it to the repo you just created. And presto! Your site will now be built for you, and deployed to Netlify's CDN network. You can setup a custom domain for the site in Netlify's admin panel.

Setup content publishing

So far you'd have to manually redeploy your site every time you publish new content in Prismic, which isn't very practical. Luckily we can tell Netlify to rebuild and redeploy our site via webhook, and Prismic can call a webhook on every content publish. Which means that our project will update within moments of publishing new content, while maintaining all the benefits of a static site.

Add a new Build Hook in Netlify under Settings -> Build & Deploy. Copy the URL it gives you, and insert it in Prismic under Settings -> Webhooks. Now Netlify will rebuild our site every time we publish on Prismic.

Going further

This is just the beginning of what you can achieve using a decoupled, serverless workflow with Prismic and Gatsby. By using Prismic Slices you can create art directed pages without additional code. So go forth and build! Let us know how you get on, share your experiences and ideas.

Tell us about your project

Get in touch