Files
ai-for-dummies/.agents/rules/astro.md
T

2.8 KiB

Rule: Astro

Binding for every .astro file.

Zero JS is the default

A component ships no JavaScript unless it has a client:* directive. Seven of this site's ten pages ship no JS today and must continue to.

  • Never add client:load without justifying it in the PR description.
  • Prefer, in order: no JS → client:visibleclient:idleclient:load.
  • An island is a leaf, not a wrapper. Hydrate the tab panel, not the page.

Islands in this project

Only these need interactivity. Anything else claiming island status is wrong:

Island Why Directive
Guide phase/tab switchers click-driven panel swap client:visible
Review desk catalog + file viewer search, filter, fetch source files client:load
Vote widget talks to vote-service/ client:visible
Language toggle swaps EN/PT across the page client:idle

Structure

---
// 1. imports
// 2. Props interface
// 3. destructure Astro.props
// 4. derived values — no side effects, no fetch in components
---

<!-- markup -->
<style>
  /* component-scoped */
</style>
  • Typed props always: interface Props { … }, then const { … } = Astro.props.
  • Data loading belongs in src/content/ collections or the page frontmatter, not inside a component.
  • No barrel files (index.ts re-export hubs). They cost tree-shaking and invite cycles.

Content collections

All copy lives in src/content/, typed with a Zod schema in src/content/config.ts. The review desk's catalog.js maps onto a collection almost one-to-one — do that rather than importing a 27 KB JS file.

Styles

  • Component styles go in the component's <style> block. Astro scopes them.
  • Only tokens and true resets live in global CSS.
  • Do not port responsive.css verbatim. It is an override layer whose reason for existing disappears once layout is componentized. Port what a component needs, prove the rest is dead, delete it.

URLs and the base path

The site is served from /ai-for-dummies/. Set base in astro.config.mjs and never hand-write an absolute internal path. Use import.meta.env.BASE_URL.

Existing routes are load-bearing and must not change, including trailing slashes and the review desk's query params.

Never

  • No UI framework (React/Vue/Svelte) unless a task brief explicitly calls for it. Astro components plus a little vanilla JS cover everything here.
  • No CSS framework. This site has a hand-built visual identity — see theming.md.
  • No external runtime requests. Self-host. audit-ui.mjs enforces it.