# 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.