Personal website and blog for Nick Thiru — built with SvelteKit, TailwindCSS, and markdown-in-repo publishing.
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run previewsrc/
├── content/
│ └── posts/ # Markdown blog posts
├── lib/
│ ├── components/ # Reusable Svelte components
│ ├── utils/ # Helper functions
│ └── config.ts # Site configuration
├── routes/
│ ├── +layout.svelte # Root layout
│ ├── +page.svelte # Home page
│ ├── writing/ # Blog post listing & detail
│ ├── engineering/ # Technical posts (filtered)
│ ├── operating/ # Operator posts (filtered)
│ ├── projects/ # Projects showcase
│ ├── about/ # About page
│ ├── now/ # Now page
│ ├── subscribe/ # Email subscription
│ ├── rss.xml/ # RSS feed
│ └── sitemap.xml/ # XML sitemap
└── app.css # Global styles (Tailwind)
- Create a new
.mdfile insrc/content/posts/:
---
title: "Your Post Title"
slug: "your-post-slug"
description: "A brief description for SEO and cards."
publishedAt: "2025-01-20"
track: "technical" # or "operator"
tags: ["tag1", "tag2"]
draft: false
---
Your post content here...- Save and the post will appear automatically.
| Field | Type | Required | Description |
|---|---|---|---|
title |
string | Yes | Post title |
slug |
string | Yes | URL slug (no leading slash) |
description |
string | Yes | 1-2 sentence summary |
publishedAt |
string | Yes | ISO date (YYYY-MM-DD) |
track |
"technical" | "operator" |
Yes | Content category |
tags |
string[] | No | Topic tags |
draft |
boolean | No | Hide from production if true |
updatedAt |
string | No | ISO date if updated |
canonical |
string | No | Canonical URL if cross-posted |
image |
string | No | OG image path |
Posts are categorized into two tracks:
technical— Engineering content: architecture, code, infra, benchmarks, postmortemsoperator— Business content: positioning, pricing, distribution, customer insights
The track determines which filtered index the post appears in:
/writing— All posts/engineering— Posts withtrack: "technical"/operating— Posts withtrack: "operator"
Set draft: true in frontmatter to hide a post from production builds.
During development (npm run dev), drafts are visible so you can preview them.
- Push your code to GitHub
- Go to vercel.com and create a new project
- Import your GitHub repository
- Vercel will auto-detect SvelteKit and configure the build
The project uses @sveltejs/adapter-vercel for server-side rendering and API routes.
- Production: Every push to
maintriggers a production deploy - Previews: Every PR gets a preview deployment URL
- Go to Project Settings → Domains
- Add
nickthiru.dev - Update DNS as instructed
See docs/newsletter-subscription.md for full details.
| Variable | Required | Description |
|---|---|---|
BREVO_API_KEY |
Yes | Brevo API key for newsletter subscription |
BREVO_WEBHOOK_SECRET |
Yes | Shared secret for webhook authentication |
PUBLIC_URL |
Yes | Base URL for DOI redirect (e.g., https://nickthiru.dev) |
- Framework: SvelteKit
- Styling: TailwindCSS with Typography plugin
- Markdown: mdsvex
- Syntax Highlighting: Shiki
- Email: Brevo (Double Opt-In newsletter + welcome email, shared with thiru-ai-labs)
- Deployment: Vercel
- Newsletter Subscription System — Brevo DOI flow, webhooks, env vars
- Route Structure — Site routing and pages
- Components Usage — Reusable Svelte components
Content is © Nick Thiru. Code is MIT licensed.