# AGENTS.md Rules for an Astro Static Site

> A drop-in AGENTS.md for Astro static sites that keeps AI agents on-stack, prevents SSR drift, and enforces content collection conventions.

**Type:** Rule  
**Tools:** Cursor, Claude Code, Codex, Windsurf  
**Stack:** Astro, TypeScript, Tailwind  
**Updated:** 2026-06-08

---

Drop this in your repo root as `AGENTS.md`. Astro-targeting agents (Cursor, Claude Code, Codex) read it automatically on startup and use it to stay on-convention across every code generation session.

## AGENTS.md

```md title="AGENTS.md"
# Project Rules — Astro Static Site

## Stack
- Astro 5 (static output, `output: "static"`). No SSR adapter unless explicitly requested.
- TypeScript strict mode. All `.astro` component scripts are TypeScript.
- Tailwind CSS v4. No CSS-in-JS. No inline `style` attributes unless value is truly dynamic.
- Content managed via Astro Content Collections (Zod schemas in `src/content.config.ts`).

## Hard rules
- Never switch `output` to `"server"` or `"hybrid"` — this is a static build.
- Never add `client:load` to a component that does not require browser interactivity.
  Prefer `client:idle` or `client:visible` when a client directive is genuinely needed.
- All content files live in `src/content/<collection>/`. Do not create ad-hoc markdown
  files outside a defined collection.
- Frontmatter must match the Zod schema in `src/content.config.ts`. Validate before
  writing — wrong field names cause build failures, not runtime errors.
- Images must go through Astro's `<Image />` component or `getImage()` helper.
  Never use bare `<img>` tags — they bypass optimisation and break CLS scores.
- Never read environment variables with `import.meta.env` inside a `.ts` utility that
  may be imported on the client; mark those files with a `// server-only` comment and
  import them only from `.astro` files or API endpoints.
- Do not add a dependency without stating the reason. Prefer Astro-native solutions
  (content collections, view transitions, image optimisation) before reaching for npm.

## Conventions
- Components live in `src/components/`. Page layouts live in `src/layouts/`.
  One component per file; file name matches the exported component name.
- Route pages live under `src/pages/`. Dynamic routes use bracket notation:
  `src/pages/[slug].astro`. Static paths are generated via `getStaticPaths()`.
- Shared TypeScript utilities live in `src/lib/`. Import with the `@/` alias
  (configured in `tsconfig.json`).
- Tailwind classes follow mobile-first order: base → `sm:` → `md:` → `lg:`.
  No arbitrary values unless a design token does not exist.
- Every page component must export a `<meta>` block via the layout that includes
  `title`, `description`, and Open Graph tags.

## SEO conventions
- Every `src/pages/*.astro` page must render a canonical `<link rel="canonical">`.
- Blog / content pages must include `datePublished` and `dateModified` in
  JSON-LD structured data.
- Do not create two pages that share the same `<title>` or `<meta name="description">`.

## Definition of done
- `astro check` passes with zero errors.
- `astro build` completes without warnings.
- Lighthouse performance score ≥ 90 on a representative page (run `unlighthouse`).
- No new `any` types. No unused imports.
- All new content frontmatter passes the Zod schema (`bun run typecheck`).
```

## Why these rules

- **"Never switch output to server"** is the highest-leverage rule for static Astro sites. Agents that discover a missing feature frequently suggest adding an SSR adapter as a quick fix — this silently changes the deployment target, breaks CDN caching, and adds cold-start latency. The rule forces agents to solve problems within the static paradigm.
- **"Images must go through `<Image />`"** eliminates the most common AI mistake on content sites: bare `<img>` tags that tank Core Web Vitals. Astro's image pipeline handles format conversion, responsive `srcset`, and lazy loading automatically — agents bypass it unless explicitly told not to.
- **Zod frontmatter validation** catches schema mismatches at typecheck time rather than at build time or, worse, silently rendering wrong data. Agents that write markdown files often hallucinate frontmatter field names.

## Good fit

- Marketing sites, blogs, documentation sites, and SEO-focused content sites built on Astro with a fixed static output target.

## Not a fit

- Astro projects using `output: "server"` or `"hybrid"` with an edge/SSR adapter — those need a different rule set that allows `client:load` and server-side data fetching patterns.