My personal site — writing, work, and projects. Live at ddlawson.com.
pnpm install
pnpm dev # localhost:4321| Command | What it does |
|---|---|
pnpm dev |
Start the dev server |
pnpm build |
Type-check and build for production |
pnpm preview |
Preview the production build locally |
pnpm lint |
Lint with Biome |
pnpm fix |
Auto-fix lint issues |
pnpm format |
Format files with Biome |
pnpm types |
Run TypeScript in --noEmit mode |
pnpm generate:og |
Regenerate Open Graph images |
- Framework — Astro 6 (static output)
- Styling — Tailwind CSS v4 via the Vite plugin
- Linting/formatting — Biome
- Hosting — Cloudflare Pages
- Analytics — Umami
- Fonts — Bricolage Grotesque (display) + Outfit (body), served via Astro Fonts
- Icons — astro-icon + Tabler
- Git hooks — Lefthook
Every push to main deploys to Cloudflare Pages via the deploy workflow. Pull requests run the validate workflow for type-checking and lint.
| Secret | Purpose |
|---|---|
CF_API_TOKEN |
Cloudflare API token with Pages edit permission |
CF_ACCOUNT_ID |
Cloudflare account ID |
UMAMI_ID |
Umami analytics website ID (optional) |
Staging deploys to ddlawson-staging.pages.dev and is gated behind Cloudflare Access — configure allowed identities in the Zero Trust dashboard.
src/
├── assets/ # images, svgs, global styles
├── components/ # Astro components
├── content/ # blog posts, projects, work history (content collections)
├── layouts/ # page layouts
├── pages/ # routes
├── utils/ # helpers
├── content.config.ts
└── site.config.ts # site-wide config (name, SEO, analytics)
functions/ # Cloudflare Pages Functions
scripts/ # one-off build scripts (e.g. OG image generation)
Content (writing, images) © David D Lawson. Code is available for reference — feel free to take inspiration, but please don't clone the site wholesale.