Set up a blog with Contentful

Using Migrateful to codify your schema

18 September 2021

In a previous post, I described how Contentful uses environments to ease application development. We can take this one step further by using Migrateful to maintain the schema as code and automatically handle environment migrations. In this short guide, I will walk through setting up a simple blog using Contentful as the backend and Migrateful as the migration manager.

Set up the space

First, you need to create a new space on Contentful. Follow the guide on the Migrateful readme. There are three things that you need:

  • space id
  • access token
  • opt-in to the master environment alias

Create a schema file

In your project's root directory, create a new folder called migrations. You will put your schema files here so that Migrateful can locate them and apply them to new Contentful environments. Create a new file in this folder called migrations/01-blog-post.js that will contain all the fields needed for storing blog posts. Below is an example of how your schema might look, but feel free to modify this to fit your own requirements using Contentful's content model.

module.exports = function (migration) {

    const post = migration.createContentType('post')
        .name('Post')
        .description('Blog post')
        .displayField('title')

    post.createField('title')
        .name('Title')
        .type('Symbol')
        .required(true)

    post.createField('slug')
        .name('Slug')
        .type('Symbol')
        .required(true)

    post.createField('description')
        .name('Description')
        .type('Text')
        .required(true)

    post.createField('body')
        .name('Body')
        .type('Text')
        .required(true)

    post.createField('published')
        .name('Published')
        .type('Date')
        .required(false)

}

Run the migration

Migrateful will need your Contentful credentials in order to run the migrations on your behalf. Specify the space id and access token using environment variables.

export CONTENTFUL_SPACE_ID=<spaceId>
export CONTENTFUL_ACCESS_TOKEN=<token>

Now you can run migrateful. This will pick up your migration, create a new environment in Contentful, apply the schema changes, and re-alias the new environment to be master. If you make a mistake, you can always roll back the Contentful alias to point to your old environment.

npx migrateful main

Now you can navigate to your Contentful console and start writing your first blog post :D

Setup a Github action

While it is not necessary to use your new Contentful backend, you can easily set up a Github action that automatically triggers your migrations when you commit changes to your migrations folder. Once you have a repo setup on Github, add your space id and access token to the repo secrets Repo SettingsSecretsNew repository secret. Then, in the root directory of your repo, create .github/workflows/deploy.yml.

# deploy.yml

name: Blog

on:
  push:
    paths:
      - '.github/**'
      - 'migrations/**'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
        with:
          node-version: '16'
      - name: Run migrations
        run: npx migrateful ${GITHUB_REF#refs/heads/}
        env:
          CONTENTFUL_ACCESS_TOKEN: ${{secrets.CONTENTFUL_ACCESS_TOKEN}}
          CONTENTFUL_SPACE_ID: ${{secrets.CONTENTFUL_SPACE_ID}}

Now, whenever you push to the master branch, Migrateful will create your new master environment. If you want to create a test environment, just push to a new branch called dev or my-feature, and Migrateful will create a new environment with that name.