First post, so a quick tour of how this site is put together.
The stack
- Next.js (App Router) with
output: "export"— the whole site compiles to static HTML at build time. No server, no cold starts, nothing to patch at runtime. - Based on Dillion Verma's Magic UI portfolio template (MIT) — all personal content lives in a single
resume.tsxconfig file, which keeps content changes trivial. - Tailwind CSS v4 + shadcn/ui + Magic UI for styling and the small animations.
- content-collections for the blog — posts are
.mdxfiles in acontent/directory, with frontmatter validated by Zod at build time. The schema is strict on purpose:publishedAtis checked as an ISO date, so a typo in the field name or the value fails the build instead of silently rendering "Invalid Date".
Deploys
The repo is connected to Workers Builds: every push to main runs next build and publishes the out/ directory as Workers static assets on this domain. Rollback is redeploying a previous build.
Push-to-deploy cuts both ways, though — with no staging step, a half-written post would go live the moment it's committed. So the content pipeline has one gate: posts marked draft: true are filtered out of the routes, the blog index, and the sitemap at build time. A draft can sit on main indefinitely without ever being published.
Security headers ship from a _headers file next to the static assets — CSP, HSTS, nosniff, X-Frame-Options: DENY — and the zone redirects all HTTP to HTTPS at the edge, so none of it depends on application code.
The gotcha that almost blocked this post
output: "export" has one sharp edge: a dynamic route like blog/[slug] fails the entire build if its generateStaticParams() returns an empty array. With zero posts, the blog index page built fine — but the post route itself couldn't.
The workaround while the blog was empty: name the route folder _slug instead of [slug]. The underscore prefix marks it as a private folder, excluding it from routing entirely, so the export never tries to build it. The rename back to [slug] shipped in the same commit as this first post — the commit that published the page you're reading.