An Astro 4 static blog with client-side encrypted content. Posts are encrypted at build time and decrypted in the browser using a passphrase passed via URL query parameter.
- Plain Markdown posts live in
src/content/posts-src/(not committed) pnpm encryptencrypts each post body with AES-256-GCM + PBKDF2-SHA256 and writes the result tosrc/content/posts/- Only encrypted posts are deployed
- Readers access posts via
?key=<passphrase>— the browser decrypts and renders the content client-side
Encryption uses globalThis.crypto.subtle (Web Crypto API) on both sides, guaranteeing identical behaviour in Node.js 18+ and modern browsers.
| Command | Action |
|---|---|
pnpm install |
Install dependencies |
pnpm dev |
Start dev server at localhost:4321 |
pnpm encrypt |
Encrypt posts from posts-src/ → posts/ |
pnpm build |
Encrypt + type-check + build to ./dist/ |
pnpm preview |
Preview production build locally |
# 1. Install dependencies
pnpm install
# 2. Set your encryption passphrase
echo "ENCRYPT_KEY=your-passphrase" > .env
# 3. Add plain posts to src/content/posts-src/
# 4. Build
pnpm buildAppend ?key=<passphrase> to any post URL:
https://yoursite.com/posts/my-post?key=your-passphrase
- Astro 4 — static site framework
- React 18 — client-side interactivity
- Web Crypto API — AES-256-GCM encryption
- marked — client-side Markdown rendering
- DOMPurify — XSS sanitisation
- TypeScript 5 (strict)