This past weekend, my family and I relocated to Amsterdam for the opening of Rangle's first European office. When we left our home in Toronto, friends and family said farewell and told us to post lots of photos and send updates to them back home.

We decided that the best thing we could do to document our year abroad — for our family and our future selves — is to keep a personal blog that we'd fill with our reflections and stories over the year.

We don't want the blog to be shared widely or ever go viral, so in deciding the blog framework to use, I thought it best if we created the blog ourselves, away from the popular community blog websites.

My design criteria for developing the blog was as follows:

  • Be very quick to set-up
  • Be very affordable to host and manage
  • Be very easy for my partner and I to update

I decided the best solution was to use the static-site generator Gatsby, with code hosted on GitHub, deployments handled by Netlify, content managed using Netlify CMS and password protection managed by Auth0.

Here is how I built my family's Amsterdam blog on the second day of arriving — through the fog of jet lag.

Install Gatsby CLI

npm install -g gatsby-cli

Create Gatsby project using a starter

I used the gatsby-blog-starter to provide the scaffolding for our project.

gatsby new amsterdam-blog https://github.com/gatsbyjs/gatsby-starter-blog

Open the newly created project:

cd amsterdam-blog

Run locally

To confirm everything is set up correctly and to see the default behaviour of the starter, run the project locally:

gastby develop

There should be three blog posts in the browser, with a default header and footer.

In the root of the amsterdam-blog folder, there is a subfolder called content that looks like this:

These markdown files *.md are what generate the blog's content.

Set-up GitHub repository

In GitHub, create a New Repository. Set the repository name to amsterdam-blog and chose the Private option.

In the terminal, add the the GitHub repository to your local repo:

git remote add origin <your-github-ssh-address>

Push the local changes to GitHub:

git push -u origin master

Create a Netlify account & set-up automated deployments

Go to Netlify and create a free account (I signed up using GitHub). Once logged in, connect the GitHub repository created above to Netlify:

  • Select Sites > New site from Git
  • Select Continuous Deployment > GitHub
  • Authorize access to GitHub, if prompted
  • Select the repository amsterdam-blog
  • Keep the default selections
  • Deploy site

The site will be deployed to the public domain displayed at the top of the overview page.

Add Netlify CMS to publish content

Manually writing blog posts in markdown and storing them in the /content/blog folder doesn't seem like a convenient solution for my partner and I to publish content. Instead, set up Netlify CMS.

npm install --save netlify-cms-app gatsby-plugin-netlify-cms

Add the plugin to the gatsby-config.js somewhere in the existing plugin array:

plugins: [     
       { ...other plugins },     
       'gatsby-plugin-netlify-cms',
       { ...other plugins } 
]

Add Identity to Netlify account

Users must have credentials and be authorized to access Netlify CMS. To enable Netlify Identity:

  • On the Netlify project page, select Settings
  • Select Identity > Enable Identity
  • Scroll down to Registration > Edit Settings > Invite Only to allow only invited users to edit your blog
  • Scroll down to Services and selected Enable Git Gateway

Configure Netlify CMS

Within the static folder of the Gastby project, create a folder named admin and within that folder create a file named config.yml.

Open the config.yml file and add the following content:

backend:   
    name: git-gateway
    branch: master  
    
media_folder: static/img 
public_folder: /img  

collections:   
- name: "blog"
  label: "Blog"
  folder: "content/blog"
  create: true
  slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
  editor:
      preview: false
  fields:
  - { label: "Title", name: "title", widget: "string" }
  - { label: "Publish Date", name: "date", widget: "datetime" }
  - { label: "Description", name: "description", widget: "string" }
  - { label: "Body", name: "body", widget: "markdown" }

Invite authors

Invite people to be blog authors:

  • Go to Netlify
  • Select Identity in the top menu > Invite Users > Input an email address (try yours first)
  • An email invite should be sent to the user.
  • Click the link to confirm the registration and create a password
  • User is logged into the blog's CMS

Write a post

Write the first post.

  • Log into the CMS by going to https://<your-blog>.com/admin
  • Select New Blog
  • Complete each of the fields in the blog authoring page
  • Add an image
  • Select Publish

When you select Publish the changes will not appear on the live website immediately.

What happens when you click Publish is the Netlify CMS takes your content and commits it to your GitHub repo in a file located at content/blog(markdown) and static/img (images). Go have a look at your GitHub commit history to prove it!

This commit prompts the Netlify Continuous Deployment to trigger and redeploy the website with the new blog post.

After a rebuild on Netlify, the new blog post will be displayed.

Remove default posts provided by starter

Now is a good time to remove those default blog posts that came with the starter. But, before making any changes locally, git pull to get the new blog post that you create with the CMS.

Once the local repo is up to date:

  • Delete the default blog folders in content/blog
  • git commit your changes
  • git push to redeploy

Customize Blog

Update the Gatsby Blog Starter's default content — particularly the bio, footer, and metadata — and the default URL that Netlify assigns the site.

Password Protect

Since I want this blog to be for friends and family only, I'd like to require users to enter a password to access the content. Netlify offers this capability with their Visitor Access Control feature. Unfortunately this feature is not part of Netlify's free plan.

I want to keep this project as affordable as possible, so I looked into other solutions. It turns out Auth0 has a great tutorial on creating protected directories in Gatsby. Follow this tutorial to protect the blog behind a login screen.

Note: The Auth0 tutorial looks at protecting the directory /account/*. In my case, I wanted to protect every directoy /*.

DEVIATIONS FROM AUTH0 TUTORIAL

blog-post.js

Add the same isAuthenticated test to blog-post.js as was added to index.js

// src/templates/blog-post.js 
...
import { login, isAuthenticated } from "../utils/auth"  

class BlogPostTemplate extends React.Component {     
    render() {          
        ....          
        if (!isAuthenticated()) {               
            login()               
            return <p>Redirecting to login...</p>          
        }          
        ...     
    } 
}

gatsby-node.js

Change the function to do the following:

// gatsby-node.js  

exports.onCreatePage = async ({ page, actions }) => {     
    const { createPage } = actions     
    page.matchPath = "/*/*"     
    createPage(page) 
}

gatsby-config.js

The Auth0 integration will conflict with the Netlify CMS Identity. To avoid this, make the following change in gatsby-config.js:

{
    resolve: `gatsby-plugin-netlify-cms`,
    options: {
        enableIdentityWidget: false
    } 
}

Turn off Auth0 Sign-up

To prevent people from registering for the blog, turn off Auth0's default sign-up feature:

  • Log into Auth0
  • Select Connections > Database
  • Select Username-Password-Authentication
  • Under Settings toggle
  • Disable Sign Ups

Provide readers access to the blog

There are two ways to approach this: (1) Create one account using your email address and password that you share to all your readers, or (2) In Auth0, enter all the email addresses of the users you want to access the blog and require them to verify their email.

Since this blog is just for friends and family, I am comfortable creating an account with my email address and emailing my invite list the credentials for them to access the blog.

Obviously, this isn't a secure solution, but it's secure enough for this project.

Dat is het!

You now have a CMS powered blog that is continuously deployed on each code commit and each time you publish a new post from the browser.

Sources

Much of this blog was the compilation of three different sources: