# Astro Static Site + Content Collections + Tailwind — AI Agent Guidelines & Architecture Rules

> Rules for a fully static Astro 7 site: content collections with Zod schemas, zero-JS pages with rare islands, build-time sitemap and OG images, and static hosting on Cloudflare.
> Technologies: Astro, Tailwind CSS, TypeScript, MDX, Cloudflare

---

## AGENTS.md
```markdown
# Project Architecture & Guidelines (Astro Static + Content Collections)

## 1. System Architecture
- **Framework**: Astro 7 with `output: 'static'` (the default). No server adapter; every route is HTML at build time.
- **Content**: Content collections defined in `src/content.config.ts` with the `glob()` and `file()` loaders and a Zod schema per collection.
- **Styling**: Tailwind CSS with a small token set in the config; no runtime CSS-in-JS.
- **Interactivity**: Astro components by default. A React, Svelte or Vue island only where state must survive after load, hydrated with `client:visible` or `client:idle`, never `client:load` by habit.
- **Hosting**: Static files on Cloudflare (Workers static assets or Pages). No functions unless a form or API genuinely needs one.
- **Runtime**: Node 22.12+ for the build (Astro 6 dropped Node 18 and 20).

## 2. File Layout
- `src/content.config.ts`: Every collection, its loader and its schema in one file.
- `src/content/<collection>/`: Markdown or MDX entries; file name is the slug.
- `src/pages/`: File-based routes. Dynamic routes export `getStaticPaths()` built from `getCollection()`.
- `src/layouts/Base.astro`: The only place that writes `<head>`: title, description, canonical, Open Graph, JSON-LD.
- `src/components/`: `.astro` components; islands live in `src/components/islands/` so they are easy to count.
- `src/pages/sitemap.xml.ts`, `rss.xml.ts`, `og/[...slug].png.ts`: Build-time endpoints, prerendered like pages.

## 3. Content Rules
- Every frontmatter field is in the collection schema. Adding a field means changing the schema first; the build fails on missing or mistyped fields.
- Use `z.coerce.date()` for dates and `reference()` for links between collections instead of raw slugs.
- Query with `getCollection()` / `getEntry()` and render with `render(entry)`. The legacy `getEntryBySlug()` API was removed in Astro 6.
- Drafts use a `draft: z.boolean().default(false)` field filtered out in one helper, not in every page.

## 4. SEO & Performance
- One layout owns all meta tags; pages pass `title`, `description` and `image` props, never raw `<meta>`.
- Canonical URLs match the served URLs exactly (pick a trailing-slash policy in `astro.config.mjs` and the host, and keep them aligned).
- Generate the sitemap, RSS feed and OG images at build time. Nothing about a static page should be computed per request.
- Use `astro:assets` `<Image />` for local images so width, height and modern formats are emitted at build.

## 5. Coding Standards
- Strict TypeScript (`astro/tsconfigs/strict`), zero `any`.
- Keep logic out of `.astro` templates: data shaping goes in `src/lib/*.ts`, which can be unit tested.
- No client-side router, no global state library, no CMS until the content outgrows a folder of Markdown.

## 6. Testing Conventions
- `astro check` and `astro build` are the test suite for content: both must pass in CI.
- Unit test `src/lib/` helpers (slugs, dates, sorting) with Vitest.
- Add a build-time assertion for the invariants that matter, e.g. every indexable page has a canonical URL and a description under 160 characters.

## 7. Git Workflow & PR Conventions
- Conventional Commits scoped to the area: `feat(blog): add series field`, `fix(seo): canonical for paginated lists`.
- A schema change and the content edits it requires land in the same PR.
- Preview deploys per PR; review the rendered page, not only the Markdown diff.
```

---

## CLAUDE.md
```markdown
# CLAUDE.md — Astro Static Site Commands & Conventions

> Claude Code also reads `AGENTS.md` when no `CLAUDE.md` is present — keep this file for Claude-specific directives.

## Common Commands
- `npm run dev` - Start the dev server (`astro dev`)
- `npm run build` - Static build to `dist/` (`astro build`)
- `npm run check` - Type-check `.astro`, `.ts` and content schemas (`astro check`)
- `npm run preview` - Serve the built `dist/` locally

## Code Style Guidelines
- Change `src/content.config.ts` before adding a frontmatter field to any entry.
- Default to `.astro` components; ask before adding a framework island.
- Never add an SSR adapter to fix a static problem; generate the data at build time instead.
```

---

## .cursor/rules/stack.mdc
```markdown
---
description: Astro static site with content collections
globs: ["src/**/*.astro", "src/**/*.ts", "src/content/**/*.md", "src/content/**/*.mdx"]
alwaysApply: true
---

# Astro Static + Content Collections

- Astro 7, `output: 'static'`, no adapter. Node 22.12+ for builds.
- Collections in `src/content.config.ts` with `glob()`/`file()` loaders and Zod schemas; schema first, content second.
- `getCollection()`/`getEntry()` + `render(entry)`; never the removed `getEntryBySlug()`.
- `.astro` components by default; islands only for post-load state, with `client:visible`/`client:idle`.
- One layout writes all `<head>` tags; sitemap, RSS and OG images are build-time endpoints.
- `astro check` and `astro build` must pass before merge.
```

---

## Architecture Overview & Best Practices
## Architecture Overview

Guidelines for a **fully static Astro 7** site: Markdown and MDX in **content collections** with Zod schemas, **Tailwind CSS**, and the occasional island, deployed as plain files to **Cloudflare**.

### Key Advantages

- **Nothing to run after deploy**: a static build either succeeds or fails, so there is no runtime state for an agent to debug in production.
- **Schemas on content**: every frontmatter field is typed, so "add a field to every post" is a change the type checker verifies.
- **SEO done once**: one layout owns the head, and the sitemap, feed and social images are generated with the pages.