# AGENTS.md — Astro - Default to zero client-side JavaScript: Astro renders components to HTML & CSS and strips JS. - A `.astro` file = component script in a `---` fence (runs at build/server time, stripped from output) + an HTML template with `{ }` expressions. - Read props from `Astro.props`; type them with `interface Props`. Use `` and named slots for composition. - Add interactivity only as islands: framework components marked with a `client:*` directive ship JS, nothing else does. - Choose the lightest directive: `client:load` (immediate), `client:idle` (browser idle), `client:visible` (in viewport), `client:media={QUERY}`, `client:only="framework"` (client-only render). - No directive means the framework component renders to static HTML with no JS — keep it that way unless interactivity is required. - Plain `.astro` components cannot take `client:*`; only framework components hydrate. Use `server:defer` for dynamic server islands. - Only Astro components can combine multiple UI frameworks; framework components cannot import `.astro` files. - Props to a hydrated island must be serialisable (no functions). Pass children via `children` (React/Preact/Solid) or `` (Svelte/Vue). - Store structured content in content collections, outside `src/pages/`. - Define collections in `src/content.config.ts` with `defineCollection()`, a loader (`glob()`/`file()`), and a Zod `schema` for type-safe frontmatter. - Query collections with `getCollection()` / `getEntry()` and render entries with `await render(entry)` (the `{ Content }` it returns), all from `astro:content`. - Don't add `client:*` to non-interactive UI, pass functions as island props, or skip the collection schema.