NetlifyCMS with GitHub OAuth authentication hosted on Vercel
- Published
- 2021-05-23
- Tags
- Next.jsNetlifyCMSVercelGuideOAuthGitHub
Recently, I was moving www.danielamulle.at to Vercel while transitioning to Next.js from Gatsby. The transition went quite smooth in general, but one thing I didn't expect troubles with was making NetlifyCMS work on Vercel.
NetlifyCMS is a great headless content management system that has good defaults, is flexible enough to fulfill most needs, has a pluggable API, and works well if you host your content on GitHub. I have also contributed to the project when it was at the very early stage. For obvious reasons, Netlify CMS works really well when you host on Netlify but unfortunately things become a bit more complicated if you decide to move to another hosting provider.
This is due to a requirement of GitHub’s authentication flow. To use a GitHub backend with NetlifyCMS, you have to run your own server to handle OAuth or use serverless provider like Vercel.
Netlify substitutes the need for the server and makes it work out-of-the-box but it also might feel like a verndor lock-in. Fortunately, there are open source solutions that implement everything needed but setting everything up can take some time. This is a step-by-step guide of things that worked for me.
Step 1. Configure Netlify CMS
Put you config.yml
file to /public
so it's accessible by NetlifyCMS when deployed to production. Open the file and additionally to your existing config you need to:
- Set
repo
to your GitHub repo that contains the source code of your site.
- Set
base_url
to the production domain with HTTPS protocol, for example,https://www.danielamulle.at
in my case.
- Add
auth_endpoint: api/auth
. This is the URL that NetlifyCMS will open when you click "Authenticate" button. We'll implement this endpoint in our next.js app later.
I've also enabled local_backend: true
in the config to make CMS work with the local git without going over the server when in development mode. You can read about making NetlifyCMS to work with a local git repository.
Step 2. Create GitHub App
Go to GitHub and navigate to Settings → Developer settings → GitHub Apps → New GitHub App or use this direct link.
It's not important how you'll name the app since it will not be published. Fill User authorization callback URL
with the URL https://<domain>/api/callback
. Use exactly the URL that you entered as base_url
at the previous step.
Disable Webhook checkbox and set permissions to Read & Write
for "Contents":
Hit "Create app" and on the next page you'll see the app details with Client ID
and Client secret
. We will need those on the next step.
Step 3. Set environment secrets
Add those values to Vercel environment variables:
vercel env add secret OAUTH_CLIENT_ID <client-id-of-GitHub-App>
vercel env add secret OAUTH_CLIENT_SECRET <client-secret-of-GitHub-App>
Step 4. Setup OAuth client in Next.js app
Install https://github.com/bericp1/netlify-cms-oauth-provider-node as a dependency to your project:
npm install netlify-cms-oauth-provider-node
and create a .env
file to add following configuration options:
OAUTH_CLIENT_ID=
OAUTH_CLIENT_SECRET=
COMPLETE_URL=https://<domain>/api/callback
ORIGIN=<domain>
where <domain>
is your domain without https. It's important to match COMPLETE_URL
here and in the GitHub App so make sure they are the same.
Then create 2 files: /src/pages/api/auth.js
and /src/pages/api/callback.js
import { createVercelBeginHandler } from "netlify-cms-oauth-provider-node"
module.exports = createVercelBeginHandler({}, { useEnv: true })
import { createVercelCompleteHandler } from "netlify-cms-oauth-provider-node"
module.exports = createVercelCompleteHandler({}, { useEnv: true })
After that, push the code to production branch on Vercel and wait till it's deployed. Navigate to your site and go to the CMS URL. You should be able to authenticate with GitHub now.
Credits
Huge thanks to @bericp1 for https://github.com/bericp1/netlify-cms-oauth-provider-node and @robinpokorny for https://github.com/robinpokorny/netlify-cms-now. Robin's solution didn't work for me but it led me to the right direction.