{
  "id": "agents-md-for-astro-static-site",
  "type": "rules",
  "category": "rules",
  "locale": "en",
  "url": "/rules/agents-md-for-astro-static-site",
  "title": "AGENTS.md Rules for an Astro Static Site",
  "description": "A drop-in AGENTS.md for Astro static sites that keeps AI agents on-stack, prevents SSR drift, and enforces content collection conventions.",
  "tools": [
    "Cursor",
    "Claude Code",
    "Codex",
    "Windsurf"
  ],
  "stack": [
    "Astro",
    "TypeScript",
    "Tailwind"
  ],
  "tags": [
    "agents-md",
    "astro",
    "typescript",
    "tailwind",
    "conventions",
    "seo"
  ],
  "difficulty": null,
  "updated": "2026-06-08",
  "markdown": "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.\n\n## AGENTS.md\n\n```md title=\"AGENTS.md\"\n# Project Rules — Astro Static Site\n\n## Stack\n- Astro 5 (static output, `output: \"static\"`). No SSR adapter unless explicitly requested.\n- TypeScript strict mode. All `.astro` component scripts are TypeScript.\n- Tailwind CSS v4. No CSS-in-JS. No inline `style` attributes unless value is truly dynamic.\n- Content managed via Astro Content Collections (Zod schemas in `src/content.config.ts`).\n\n## Hard rules\n- Never switch `output` to `\"server\"` or `\"hybrid\"` — this is a static build.\n- Never add `client:load` to a component that does not require browser interactivity.\n  Prefer `client:idle` or `client:visible` when a client directive is genuinely needed.\n- All content files live in `src/content/<collection>/`. Do not create ad-hoc markdown\n  files outside a defined collection.\n- Frontmatter must match the Zod schema in `src/content.config.ts`. Validate before\n  writing — wrong field names cause build failures, not runtime errors.\n- Images must go through Astro's `<Image />` component or `getImage()` helper.\n  Never use bare `<img>` tags — they bypass optimisation and break CLS scores.\n- Never read environment variables with `import.meta.env` inside a `.ts` utility that\n  may be imported on the client; mark those files with a `// server-only` comment and\n  import them only from `.astro` files or API endpoints.\n- Do not add a dependency without stating the reason. Prefer Astro-native solutions\n  (content collections, view transitions, image optimisation) before reaching for npm.\n\n## Conventions\n- Components live in `src/components/`. Page layouts live in `src/layouts/`.\n  One component per file; file name matches the exported component name.\n- Route pages live under `src/pages/`. Dynamic routes use bracket notation:\n  `src/pages/[slug].astro`. Static paths are generated via `getStaticPaths()`.\n- Shared TypeScript utilities live in `src/lib/`. Import with the `@/` alias\n  (configured in `tsconfig.json`).\n- Tailwind classes follow mobile-first order: base → `sm:` → `md:` → `lg:`.\n  No arbitrary values unless a design token does not exist.\n- Every page component must export a `<meta>` block via the layout that includes\n  `title`, `description`, and Open Graph tags.\n\n## SEO conventions\n- Every `src/pages/*.astro` page must render a canonical `<link rel=\"canonical\">`.\n- Blog / content pages must include `datePublished` and `dateModified` in\n  JSON-LD structured data.\n- Do not create two pages that share the same `<title>` or `<meta name=\"description\">`.\n\n## Definition of done\n- `astro check` passes with zero errors.\n- `astro build` completes without warnings.\n- Lighthouse performance score ≥ 90 on a representative page (run `unlighthouse`).\n- No new `any` types. No unused imports.\n- All new content frontmatter passes the Zod schema (`bun run typecheck`).\n```\n\n## Why these rules\n\n- **\"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.\n- **\"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.\n- **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.\n\n## Good fit\n\n- Marketing sites, blogs, documentation sites, and SEO-focused content sites built on Astro with a fixed static output target.\n\n## Not a fit\n\n- 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."
}