Adding a CMS to hugo

Static doesn’t mean dead

Published October 27, 2018 #hugo #howto #static_sites #netlify

Just because we have a static site doesn’t mean that we can’t have an admin tool to write and edit posts! Lets go through how we can add the NetlifyCMS to the site and host it wherever we want.

In my case I’m storing the code on GitHub and also serving the pages from GitHub Pages. Netlify also seems like a really promising company with a number of other services that they offer, so I’d encourage you to check it out. But since I’m changing one thing at a time, I’ll leave that for a later exercise.

The CMS works by loading the code and it’s configuration from your site. These are 100% static so nothing needs to happen at build time. The configuration tells the admin – which again runs totally in your browser – where to get authentication and the data for your site. Once that’s done you’ll need to figure out how to setup the build process.

Install the admin

in /static/admin/index.html:

<!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Content Manager</title>
</head>
<body>
  <!-- Include the script that builds the page and powers Netlify CMS -->
  <script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
</body>
</html>

Then in `/static/admin/config.yml:

backend:
  name: github
  repo: wschenk/willschenk.com

publish_mode: editorial_workflow

media_folder: static/img/uploads
public_folder: img/uploads

collections:
  - name: "articles"
    label: "Articles"
    folder: "content/articles"
    create: true
    fields:
      - { label: "Title", name: "title", widget: "string" }
      - { label: "Date", name: "date", widget: "date" }
      - { label: "Body", name: "body", widget: "markdown" }

What if I don’t have a netlify account?

There are a number of ways to do this, but we are going to

  1. Create a GitHub application that will do the granting
  2. Create a firebase application to handle the accounts
  3. Wire everything together.

Creating the GitHub app

Go to GitHub developer settings. You can access this by clicking on your profile, selecting Settings, and then selecting Developer Settings.

Create a New OAuth App.

Leave the callback URL blank for now – we’ll set that up with a url that we will get from firebase shortly.

Take note of the client ID and client secret, we’ll need those shortly

Creating the firebase application

We will spin up something on firebase to help handle the oauth dance.

First lets checkout some code that will handle the api interactions. We are going to install this code on firebase.

$ git clone https://github.com/Herohtar/netlify-cms-oauth-firebase
$ cd netlify-cms-oauth-firebase/functions/
$ npm i
$ cd ..

Then install firebase-tools if you haven’t already

$ npm add -g firebase-tools

Next log in to firebase

$ firebase login

Go to the firebase console and create an application. Then configure firebase to use that project

$ firebase use projectname

Now lets setup the client id and secret that we got from GitHub:

$ firebase functions:config:set oauth.client_id=yourclientid oauth.client_secret=yourclientsecret

This will take a few seconds to finish. Now we can deploy our functions, and get the URL that GitHub will use to pass back the authentication.

$ firebase deploy --only functions

Note the url of the application deployed, in my case it is https://us-central1-willschenkcom.cloudfunctions.net/oauth

Wiring it all up

Go back to the GitHub app page and change your app’s callback to the hostname/oauth/callback – in my case https://us-central1-willschenkcom.cloudfunctions.net/oauth/callback.

Then in static/admin/config.yml set the baseURL to your firebase application. In my case the relavent section looks like:

backend:
  name: github
  repo: wschenk/willschenk.com
  base_url: https://us-central1-willschenkcom.cloudfunctions.net
  auth_endpoint: /oauth/auth

Summary

The NetlifyCMS is really interesting, though its still a work in progress. With this setup, we are using a couple of external services – GitHub, Firebase – all within their free tiers to edit and push out a website. This process would probably be even easier if we went all in with Netlify, so that’s another great service to start checking out.

Originally I had configuring CircleCI in this post, but I moved it to its own! Read next!

Read next

See also

Building a hugo site and theme with Bootstrap

hugo is blazing fast

Now that’s its 2018 its time to retool the blog using hugo. Why not? Hugo is built in golang and is blazing fast and everything is cleaner than it was in the middleman years. One of the reasons that I liked middleman – it’s usage of the rails’ Sprockets library – is no longer a strength. The javascript and front-end world has moved over to WebPack and I’ve personally moved over to create-react-app.

Read more

Slow data and Fast Sites

building fast, searchable, functional sites that fail gracefully

This article walks through the motivations driving and benefits of using a the Seed Architecture for building performant websites using Middleman, React, and a seperate API server such as Parse. The benefits are: You get full SEO with a heavy client JavaScript site without having to do crazy things with PhantomJS or meta fragments. Hosting and operations become both cheap and doesn’t require a support team. Scaling out the system is mainly a bandwidth problem, and secondarily a API scaling problem for a subset of behavior.

Read more

Getting firebase and grpc working under termux

firebase depends on grpc, which isn’t set to build right on the Chromebook. This is because node-pre-gyp, which is used to download precompiled binaries, is not setup correctly. In then uses node-gyp to compile the C++ bindings directly, which is also not setup correctly. We are going to adjust the settings of node-gyp to make it compile things right under termux, and then we are going to tweak the grpc package itself in our local cache to make it build correctly.

Read more