skip to content
Jason Worden

About this site

This domain is two things stitched together: a homepage (/) 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. Astro builds everything to static HTML at deploy time — no server-side rendering, no runtime JS framework.

Homepage — Astro without a CSS framework

The homepage is also built by Astro, with hand-written CSS rather than the blog's Tailwind styles. The only JavaScript it ships is a small inline script that applies the light or dark theme, and a small deferred script for the theme toggle.

Performance

Metric Mobile Desktop
Performance score 100 100
First Contentful Paint 0.8 s 0.3 s
Largest Contentful Paint 0.8 s 0.3 s
Total Blocking Time 0 ms 0 ms
Cumulative Layout Shift 0 0
Page weight 45 KB 45 KB
Requests to first render 2 2

Lighthouse 13.6.0 lab results for the live homepage, using the median of repeated runs, from . Page weight includes Cloudflare Web Analytics. These are simulated scores, not measurements from real visitors.

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 output 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, jsonpaylo.ad & jsonreque.st

Four other domains I own, jsonpayload.com, jsonrequest.com, jsonpaylo.ad, and jsonreque.st (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.

jsonpaylo.ad and jsonreque.st are a little different operationally: they stay registered at INWX and Dynadot respectively, but their authoritative DNS is delegated to Cloudflare so the same Worker-based redirect setup can run there too.

mermaidlint.com works the same way, 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, and the script Cloudflare injects doesn't block page rendering.

Architecture at a glance

Putting it all together — from source to served site:

flowchart TD
  root["Homepage<br/>(Astro, hand-written CSS)"]
  posts["Markdown posts<br/>(Astro + Cactus blog)"]
  checks["GitHub Actions — CI (push / PR to main)<br/>· vitest (Markdown 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 · jsonpaylo.ad · jsonreque.st"]
  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