
Hello World
First post on distractedev. Why I built this, what the stack is, and a demo of every MDX component.
Hello World
First post. Ship the thing, explain later — but I'll explain anyway.
I wanted a place to write that I actually controlled end to end. No platform risk, no algorithmic feed, no tracking pixels baked in. Just an HTML file served from S3 + CloudFront.
The stack
Static site generation with React Router v7 in framework mode —
ssr: false plus prerender so every URL gets a real HTML file. No 200-fallback SPA tricks.
Posts are MDX files in content/posts/. Frontmatter is parsed at build time, syntax highlighting
runs through Shiki at build time. Zero runtime JS for highlighting.
// react-router.config.ts — prerender enumerates every post slug
export default {
ssr: false,
async prerender() {
const slugs = getPostSlugs();
return ["/", "/blog", ...slugs.map(s => `/blog/${s}`)];
},
} satisfies Config;Design: Margin Notes
The design concept is called Margin Notes. Calm editorial page in the REM typeface. Cherish is the handwritten voice that shows up in asides and the wordmark.
What you can do with mark
You can highlight a key phrase mid-paragraph to draw the reader's eye. It renders as a yellow highlighter stroke in light mode, a muted amber in dark mode.
Code blocks
A shell command:
pnpm devA TypeScript snippet with a filename:
export function calcReadingTime(raw: string): number {
const text = raw.replace(/^---[\s\S]*?---\n/m, "");
const words = text.trim().split(/\s+/).filter(Boolean).length;
return Math.max(1, Math.ceil(words / 200));
}What's next
/blog— all posts, tag filter/projects— things I've shipped/now— what I'm doing this month- OG image generation, RSS, sitemap — coming in the next build push