ehsansadeghi.me

Stack

Astro 6.3
Static framework + one SSR endpoint
Preact 10
Two interactive islands (chat, contact form)
Cloudflare Workers edge runtime
Host - prerendered HTML plus /api/chat
LangChain 1.x (core + openai)
Chat message plumbing
OpenAI gpt-5-mini
Chat model
Latin Modern Roman Computer Modern revival
Typeface - the LaTeX-preprint reference
Bun 1.3
Package manager and script runner

Decisions

  1. 01

    Astro + Cloudflare Workers, not Next.js + Vercel

    Prerender everything except the chat endpoint. One SSR route. Static assets and the Worker share a single deploy. The site costs nothing at idle and serves HTML from the edge cache.

  2. 02

    Preact, not React

    Two interactive components on this site. Preact ships ~3 kB of runtime; React would ship ~45 kB. The DX is identical - JSX, hooks, the rest. The choice is invisible to a user; it shows up as a faster first paint.

  3. 03

    Two-layer prompt-injection defense

    The system prompt explicitly tells the model to treat <user-input> contents as data, not instructions. The wrapper escapes any literal closing tag a visitor might type, so they cannot forge a fresh role boundary. Neither layer alone is enough; both together hold.

  4. 04

    Server-stateless chat

    The conversation transcript lives in the browser; the server holds no session state and caps history to the last five exchanges. Each request is logged to D1 (question, reply, salted IP hash) for rate limiting and post-hoc improvement, and purged after a year - the privacy page spells it out.

  5. 05

    Per-page prerender by default

    `output: 'server'` with `export const prerender = true` on every page except /api/chat. Static where it can be, dynamic where it must be - the configuration mirrors the architecture, not the other way around.

  6. 06

    Readable by machines on purpose

    AI crawlers are welcome here: robots.txt allows them by name, and /llms.txt plus /llms-full.txt serve the whole site as plain text in the llmstxt.org format, generated from the same data files as the HTML. If an AI answers a question about Ehsan, it should have the facts.

Source - github.com/ehsansadeghi/ehsansadeghi-me-website