skip to content
Jason Worden

About this site

This domain is two things stitched together: a static root page (/) and a blog mounted under /blog.

Stack

Blog — Markdown-based with Astro

The /blog subtree is an Astro site using the Cactus theme, customized. Posts are Markdown files in src/content/post/. Astro builds everything to static HTML at deploy time — no server-side rendering, no runtime JS framework.

Root page — plain HTML

The root page (public/index.html) is a standalone HTML file that predates the blog. It's served as-is by Cloudflare Pages. The only JavaScript it ships is a small plain-JS file that handles scroll-arrow behavior and full-height sections on desktop.

Hosting — Cloudflare Pages

Both halves deploy to Cloudflare Pages via GitHub Actions. On every push to main, the workflow builds the Astro site with pnpm and deploys the dist/ output (which includes the root page, copied verbatim from public/) using Wrangler.

Domain — Cloudflare Registrar

jasonworden.com is registered through Cloudflare Registrar and pointed at the Pages project. DNS, SSL, and CDN are all handled by Cloudflare.

Redirects — jsonpayload.com & jsonrequest.com

Two other domains I own, jsonpayload.com and jsonrequest.com (and their www hosts), point here. Each is handled by a small Cloudflare Worker — not a dashboard redirect rule — that issues a 301 to the matching path on jasonworden.com, preserving the path and query string. The Worker lives in workers/jsonpayload-redirect/ in this repo.

mermaidlint.com works the same way (workers/mermaidlint-redirect/), but redirects every path to a single fixed page — the mermaid-lint announcement post — rather than preserving the path.

Analytics — Cloudflare Web Analytics

Traffic is measured with Cloudflare Web Analytics — cookieless, no consent banner, injected automatically at the edge for every response on this domain. There's no analytics code in the source.

Architecture at a glance

Putting it all together — from source to served site:

flowchart TD
  root["public/index.html<br/>(plain HTML root)"]
  posts["src/content/post/*.md<br/>(Astro + Cactus blog)"]
  checks["GitHub Actions — CI (push / PR to main)<br/>· vitest (remark-plugin tests)<br/>· mermaid-lint (strict)<br/>· astro build"]
  deploy["GitHub Actions — deploy (push to main)<br/>astro build → Wrangler"]
  pages["Cloudflare Pages"]
  site["jasonworden.com<br/>Cloudflare Registrar · DNS · SSL · CDN"]
  analytics["Cloudflare Web Analytics<br/>(edge-injected)"]
  redirects["jsonpayload.com · jsonrequest.com"]
  worker["Cloudflare Worker<br/>(301, preserves path + query)"]
  mermaidlint["mermaidlint.com"]
  mlworker["Cloudflare Worker<br/>(301 → mermaid-lint post)"]

  root --> checks
  posts --> checks
  checks --> deploy --> pages --> site
  site --> analytics
  redirects --> worker --> site
  mermaidlint --> mlworker --> site

A flowchart in Mermaid