Introduction

Three services work together:

  • GitHub stores the website and its content. Every save in the CMS is a commit.
  • Netlify builds and hosts the website. It also acts as the OAuth server that lets Sveltia CMS sign in to GitHub.
  • Sveltia CMS is the editing interface, served on /admin/.

Content is not published on every save. Editors save as often as they want, then click Publish Changes to rebuild the website.

StepHow often
1. Connect GitHub to Netlifyonce per website
2. Create the GitHub OAuth Apponce for all your websites
3. Add the OAuth App to Netlifyonce per website
4. Configure the CMSonce per website
5. Create the Netlify build hookonce per website
6. Sign in and add the build hookonce per editor and per browser
7. Give editors accessonce per editor

Prerequisites

  • A Hugolify v2 project using Sveltia CMS - See the Sveltia CMS tutorial
  • hugolify-admin v2.0.0-26 or later, for the skip_ci option
  • A GitHub repository and a Netlify account

Step 1. Connect GitHub to Netlify

Netlify > Add new project > Import an existing project > GitHub

Pick the repository of the website, branch main, and click Deploy. The netlify.toml file of the project already holds the build command.

Host on Netlify

Step 2. Create the GitHub OAuth App

You only do this once: the same OAuth App serves all your websites hosted on Netlify, because its callback URL is always Netlify’s.

Open the form on your account, or on your organization (Organization > Settings > Developer settings > OAuth Apps > New OAuth App) so the app does not depend on a single person.

Register a new OAuth App
FieldValue
Application nameA generic name, e.g. Hugolify CMS. Editors see it on the GitHub authorization screen.
Homepage URLAny URL, e.g. your own website. It is only displayed.
Authorization callback URLhttps://api.netlify.com/auth/done
Enable Device FlowUnchecked

Click Register application, then Generate a new client secret. Copy the Client ID and the Client secret: the secret is displayed only once, so keep it in your password manager.

OAuth App, not GitHub App

Create an OAuth App, not a GitHub App. If the form shows an Expire user access tokens checkbox, you are on the wrong one: the token would expire after 8 hours and editors would have to sign in again.

Step 3. Add the OAuth App to Netlify

Project configuration > Access & security > OAuth

Under Authentication providers, click Install provider, choose GitHub, paste the Client ID and the Client secret from step 2, and click Install.

Repeat this step on every Netlify project, with the same Client ID and secret.

Regenerating the secret on GitHub means pasting it again on every Netlify project that uses it.

Step 4. Configure the CMS

/config/_default/params.yaml

admin:
  cms: sveltiacms
  name: github
  repo: owner/repo # your repository
  skip_ci: true
  auth:
    netlify_identity: false
  • skip_ci: true adds [skip ci] to every commit made by the CMS, so Netlify does not build on each save. It is the default value.
  • netlify_identity: false stops loading the Netlify Identity widget, which Sveltia CMS does not use.

No base_url is needed: without one, Sveltia CMS uses Netlify as its OAuth server.

Commit and push. Netlify builds the website with the CMS on /admin/.

Step 5. Create the Netlify build hook

A build hook is a URL that starts a Netlify build when it is called. Sveltia CMS calls it when an editor clicks Publish Changes.

Project configuration > Build & deploy > Continuous deployment > Build hooks

Click Add build hook, name it Sveltia CMS, choose the main branch, save, then copy the URL. It looks like https://api.netlify.com/build_hooks/xxxxxxxx.

Keep it secret

Anyone who knows this URL can start builds. Never commit it to the repository, and never put it in the CMS configuration, which is public.

Step 6. Sign in and add the build hook

  1. Open https://your-website/admin/.
  2. Click Sign In with GitHub, then Authorize in the GitHub window.
  3. In the top right corner, open the account menu, then Settings > Advanced.
  4. Paste the build hook URL from step 5 in the deploy hook field.

The URL is stored in the browser, not in the repository: each editor pastes it once in their own browser. Send it to them over a secure channel.

Step 7. Give editors access

  1. Each editor creates a GitHub account (free).
  2. In the GitHub repository: Settings > Collaborators > Add people, with the Write role.
  3. The editor accepts the invitation sent by email, then follows step 6.

If the repository belongs to a client’s GitHub organization that restricts third-party apps, an admin of that organization has to approve the OAuth App once.

Day-to-day publishing

Action in the CMSResult
Save[skip ci] commit, the live website does not change
Publish Changes (in the header)Calls the build hook: Netlify rebuilds the website with all saved content
Arrow next to Save > Save and PublishSaves and publishes at once
Deleting an entry or a media filePublished right away: deletions are never marked [skip ci]

A code push by a developer also triggers a build, and pending content goes live with it.

Local development

No GitHub sign-in is needed locally. Launch the project:

yarn watch

Open http://localhost:1313/admin/, click Work with Local Repository (Chrome or Edge) and select the project folder. Changes are written to the files without any commit: commit and push them yourself.

Troubleshooting

ProblemSolution
Authentication Aborted on sign-inA Cross-Origin-Opener-Policy header blocks the sign-in window. Set it to same-origin-allow-popups, or remove it.
Error or repository not found after sign-inThe GitHub account is not a collaborator of the repository, or has not accepted the invitation (step 7).
No Publish Changes buttonCheck skip_ci: true and the hugolify-admin version (v2.0.0-26 or later).
Publish Changes does not start a buildThe build hook is not set in this browser (step 6). If the website has a CSP, allow https://api.netlify.com in connect-src.
The website does not change after SaveExpected with skip_ci: true: click Publish Changes.

Going further