Skip to content

Building aidenknecht.dev

I registered aidenknecht.dev, set up its DNS and TLS on Cloudflare, and fixed a failed first deploy by moving the site to Workers static assets instead of widening the deploy token.

Date
Stack
Astro, Tailwind CSS, TypeScript, Cloudflare Workers, Wrangler

The finding

The site ships as static HTML with one stylesheet and one small client-side script, the theme toggle. It deploys itself when main changes. The design direction and the infrastructure are mine; most of the Astro, Tailwind and TypeScript code was written by Claude Code from that direction, with me reviewing and steering it.

Context

I wanted somewhere to put investigative work that reads like a lab notebook rather than a list of tools. That set the constraints: static output, no JavaScript framework on the client, one accent color, monospace only for data, and a content model where adding a project means adding one markdown file and nothing else.

What was built

  • Astro with content collections. Projects, writeups and experience are three collections in src/content/, each validated against a schema at build time. A page like this one is a markdown file with frontmatter; the layouts, lists, feed and sitemap pick it up on their own.
  • Tailwind with design tokens. Colors, fonts, the type scale and radii are declared once as theme variables, and Tailwind’s defaults are reset so a hardcoded value cannot slip in. Dark mode follows the system until the visitor chooses, and the choice is remembered.
  • Shiki at build time for KQL, PowerShell, Python and bash, with a light and a dark theme tied to the site palette. Code is highlighted HTML, not a runtime library.
  • Cloudflare in front, Cloudflare underneath. I registered aidenknecht.dev through Name.com with the GitHub Student benefit and configured its DNS and TLS on Cloudflare myself. The site itself runs on Cloudflare Workers as a static assets bundle: a GitHub push to main triggers a build and wrangler deploy.
  • The quiet parts. A sitemap, an RSS feed for writeups, a 404 page, canonical and Open Graph tags on every page, and a skip link.

Evidence

The first deploy failed. Cloudflare rejected it with an authentication error, code 10000, because the CI token had been scoped to the newer unified deploy permission, which covers wrangler deploy and not the older Pages upload. Rather than widen the token, I moved the project to Workers static assets, which is what the token was built for. The whole configuration is one file:

{
  "name": "portfolio",
  "compatibility_date": "2026-09-16",
  "assets": {
    "directory": "./dist",
    "html_handling": "drop-trailing-slash",
    "not_found_handling": "404-page"
  }
}

drop-trailing-slash matches the site’s canonical URLs, so /about serves the page instead of redirecting to /about/. 404-page serves the real 404 page with a real 404 status.

Build output, for the record:

14 page(s) built in 1.73s
sitemap-index.xml created
0 errors, 0 warnings, 0 hints (astro check)

What it means

  • The least-privilege fix is usually to move the workload, not to widen the credential. The deploy token stayed narrow and the platform changed instead.
  • A schema at build time is a cheap guardrail. A missing finding or a malformed date fails the build, not the reader.
  • Constraints made the design decisions for me. No client framework, one accent, no cards: most of what a portfolio site usually argues about was settled before the first commit.