Source code for my my personal blog.
- Astro: static site generator
- Tailwind CSS: styling
- Pagefind: client-side static search
- Satori: dynamic OG image generation at build time
- TypeScript
Based on the AstroPaper theme.
Deployed as a static site on Cloudflare Pages. Pushes to main trigger a deploy automatically.
Prerequisites: Node.js 22+ and pnpm.
# Install dependencies
pnpm install
# Start the dev server
pnpm dev
# Production build
pnpm build
# Preview the production build locally
pnpm previewThe build command runs type-checking, builds the site, generates the Pagefind search index, and copies it to the public directory.
Create a new .md file in src/data/blog/ with this frontmatter:
---
author: Gopal Krishnan
pubDatetime: 2026-01-05T03:05:04Z
title: My Post Title
slug: my-post-title
featured: false
description: A short description for SEO and post excerpts.
---
Post content in Markdown goes here.Images go in src/assets/images/ and can be referenced as .
src/
├── assets/images/ # Blog post and site images (optimized by Astro)
├── components/ # Astro UI components
├── config.ts # Site-wide configuration
├── constants.ts # Social links
├── data/blog/ # Blog posts (Markdown)
├── layouts/ # Page layouts
├── pages/ # Routes (index, about, posts, RSS, etc.)
├── styles/ # Global CSS and typography
└── utils/ # Helpers for sorting, filtering, OG generation
public/
├── favicon.svg
├── resume.pdf
└── og.png # Generated dynamically by Satori at build time
Unit tests are written with Vitest. Test files live alongside their source files (e.g. slugify.ts / slugify.test.ts).
pnpm test # Run all tests once
pnpm test:watch # Watch mode for local developmentA GitHub Actions workflow (.github/workflows/ci.yml) runs on every pull request. It lints, checks formatting, runs the unit test suite, and runs a full production build.
The source code is licensed under the MIT License. Blog content (src/data/blog/), images (src/assets/images/), and the resume (public/resume.pdf) are copyright Gopal Krishnan, all rights reserved.