· 3 min read

Adding a CMS to My Astro Blog (and the OAuth Rabbit Hole That Followed)


I recently migrated this blog from Jekyll to Astro, which I wrote about here. The content model is simple: markdown files with YAML frontmatter in src/content/blog/. Writing a post means opening a terminal, creating a file, and pushing to GitHub. Fine for code — not great when I want to jot something down on my phone or hand off editing to someone else.

So I added a CMS layer.

The choice: Decap CMS

Decap CMS (formerly Netlify CMS) is a git-based CMS that stores content directly in your repo as markdown files. There’s no database, no separate content API, no schema migration — just a web UI that commits to GitHub on your behalf. For a static Astro site, this is a perfect fit: the CMS speaks the same language as the content collections I already had.

The admin panel is a single HTML page that loads from CDN, so adding it was literally two files: public/admin/index.html and public/admin/config.yml. The config maps directly to my Astro content schema — the same fields I had in content.config.ts just described in YAML:

collections:
  - name: blog
    folder: src/content/blog
    slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
    fields:
      - { label: Title, name: title, widget: string }
      - { label: Date, name: date, widget: datetime }
      - { label: Tags, name: tags, widget: list }
      - { label: Body, name: body, widget: markdown }

This is config-driven architecture in a small but concrete form: the behavior of the system is described in a file, not hardcoded. Changing which fields appear in the editor is a YAML edit, not a code change.

The OAuth rabbit hole

The tricky part is authentication. The CMS needs to commit to GitHub on your behalf, which requires OAuth. For a static site with no server, you need an OAuth relay — a server that exchanges the GitHub auth code for a token. The standard approach is to use Netlify’s relay even if your site isn’t hosted on Netlify.

This is where things got interesting. I set up a GitHub OAuth App, pointed it at Netlify’s callback URL, configured a blank Netlify site as the relay, and got: bad_verification_code. Every time.

After debugging the callback URL, regenerating the client secret twice, and confirming the credentials were correct, I found the issue by accident: the CMS worked fine when accessed from beamish-cassata-fc006d.netlify.app/admin/ but failed from korbonits.com/admin/. Netlify’s OAuth relay only trusts requests from domains it recognizes.

The fix: add korbonits.com as a custom domain on the Netlify site. One step in the Netlify dashboard. That was it.

The result

korbonits.com/admin/ now loads a full CMS with my blog posts, the now page, and the about page all editable from the browser. Writing this post required no terminal.