Static-first personal site template built with Next.js, MDX content, and Cloudflare Pages. Contact form delivery is handled by a Cloudflare Pages Function and Mailgun.
Start with docs/quickstart.md for installation, environment variables, local development, validation commands, and deployment behavior.
Most personalization now lives in a few content files:
content/locales/en/site/profile.jsonfor name, domain, socials, metadata defaults, locale settings, and shared site identitycontent/locales/en/site/home.jsonfor homepage hero and section copycontent/locales/en/site/about.jsonfor biography, expertise, background, and principlescontent/locales/en/site/newsletter.jsonfor newsletter subjects, previews, CTA labels, confirmation/welcome copy, and recurring issue email copycontent/locales/en/site/ui.jsonfor shared UI strings, labels, status text, and theme descriptorscontent/locales/en/site/forms.jsonfor contact/newsletter form labels, placeholders, and button copycontent/locales/en/site/system.jsonfor validation, API, and fallback status messagescontent/site/newsletter-state.jsonfor recurring newsletter send historycontent/locales/<locale>/projects/*.mdxfor localized project entries, with fallback tocontent/projects/*.mdxcontent/locales/<locale>/writing/*.mdxfor localized writing entries, with fallback tocontent/writing/*.mdxpublic/headshot.jpg,public/og-default.svg, andpublic/favicon.svgfor replaceable brand assets.env.examplefor the deploy-time integration contract
To add another language, mirror the content/locales/en/ structure under a new locale directory and add it to the locale registry in src/lib/content.ts.
Contact form setup (Mailgun, Cloudflare env vars, local dev): docs/contact-form-setup.md.
Newsletter setup and recurring-send behavior: docs/newsletter-setup.md. Digest thumbnails via R2: docs/newsletter-digest-images.md.
Content entries can be created manually or generated with an LLM via pnpm content:create. The script loads the website-content skill guidelines and calls a configured provider (OpenAI, Anthropic, Google Gemini, or any OpenAI-compatible host). See docs/content-creation.md for usage, LLM provider setup, and the recommended workflow.
Read-along audio is generated and published locally to object storage (Cloudflare R2 by default); CI does not run audio steps. docs/audio-storage-workflow.md.