mode, and UI framework integration. This prevents version-specific API mismatches and output mode violations.
// AI Context Contract: Stack Declaration
export const PROJECT_STACK = {
framework: 'astro@5.2',
outputMode: 'static', // 'static' | 'server' | 'hybrid'
islands: ['svelte@5', 'solid@1.9'],
styling: 'tailwindcss@4.0',
runtime: 'node@22',
strictTypes: true
} as const;
Rationale: Astro 5 introduced the Content Layer API and server islands. Static output mode disables server-side API routes. Declaring these upfront prevents the AI from generating SSR-only patterns in a static build.
Step 2: Enforce Server-First Execution Model
.astro frontmatter executes exclusively on the server during build or request time. Browser APIs are unavailable. The context contract must explicitly forbid client-side globals in server scopes.
// AI Context Contract: Execution Boundaries
export const EXECUTION_RULES = {
serverScope: ['frontmatter', 'getStaticPaths', 'contentCollections'],
clientScope: ['<script> tags', 'island components', 'event handlers'],
forbiddenInServer: ['window', 'document', 'localStorage', 'navigator', 'fetch with credentials'],
hydrationStrategy: 'defer-unless-critical'
} as const;
Rationale: Explicitly mapping scopes prevents runtime ReferenceError exceptions during static generation. The defer-unless-critical strategy forces intentional hydration decisions.
Step 3: Mandate Framework-Specific APIs
Astro provides optimized APIs for content, images, and routing. AI models default to generic web patterns. The contract must enforce Astro-native alternatives.
// AI Context Contract: API Contracts
export const API_CONTRACTS = {
content: 'use getCollection() from astro:content',
images: 'use <Image> or <Picture> from astro:assets',
env: 'use import.meta.env.PUBLIC_* for client, import.meta.env.* for server',
routing: 'export getStaticPaths() for static dynamic routes',
styles: 'scoped by default, <style is:global> for page-level'
} as const;
Rationale: Content Collections provide schema validation and type inference. The Image component generates responsive formats and lazy loading. Enforcing these APIs ensures build-time optimization and type safety.
Step 4: Implement Validation Gates
Context files should include verification commands and linting rules. This creates a feedback loop between generation and execution.
# AI Context Contract: Validation Gates
npm run build # Verify static output
npx astro check # Type validation
npx astro build --debug # Inspect hydration boundaries
Rationale: Automated verification catches architectural violations before deployment. Debug builds expose hydration points, allowing developers to audit AI-generated boundaries.
Pitfall Guide
1. Blind Hydration
Explanation: AI defaults to client:load for every interactive component, forcing immediate hydration regardless of viewport position or criticality.
Fix: Map hydration directives to user interaction patterns. Use client:idle for non-critical UI, client:visible for below-fold content, and reserve client:load for above-the-fold interactive elements.
2. Server/Client API Leakage
Explanation: Browser globals (window, document) are placed in .astro frontmatter, causing ReferenceError during static generation or SSR.
Fix: Move all browser-dependent logic into <script> tags or island components. Use import.meta.env.SSR guards when conditional execution is required.
3. Static Output Assumption
Explanation: AI generates API routes (src/pages/api/) in static output mode, where serverless functions are unavailable.
Fix: Verify output: 'static' in astro.config.mjs. Use external APIs, edge functions, or build-time data fetching instead of server routes.
4. Raw Asset Handling
Explanation: <img> tags bypass Astro's asset pipeline, missing format conversion, lazy loading, and responsive sizing.
Fix: Import assets through astro:assets and use <Image> or <Picture>. Provide explicit dimensions for external URLs to prevent layout shift.
5. Environment Variable Misconfiguration
Explanation: AI uses process.env (Node.js pattern) instead of import.meta.env, causing undefined values in browser contexts.
Fix: Prefix client-exposed variables with PUBLIC_. Access via import.meta.env.PUBLIC_VAR_NAME. Keep secrets in unprefixed variables accessible only in server scopes.
6. Layout/Component Boundary Violation
Explanation: AI generates <html>, <head>, or <body> tags inside reusable components, duplicating document structure.
Fix: Reserve document structure for layout files in src/layouts/. Components should only render semantic markup and slots.
7. Implicit Type Fallbacks
Explanation: AI omits Props interfaces, relying on implicit any types that bypass TypeScript strict mode.
Fix: Define explicit interface Props for every component. Use Astro.props destructuring with type annotations. Enable astro/tsconfigs/strict in tsconfig.json.
Production Bundle
Action Checklist
Decision Matrix
| Scenario | Recommended Approach | Why | Cost Impact |
|---|
| Static marketing site | output: 'static' + Content Collections | Zero server costs, maximum cacheability, fast TTI | $0 hosting, minimal bandwidth |
| Hybrid dashboard | output: 'hybrid' + Server Islands | Dynamic data fetching without full SSR overhead | Moderate compute, scalable CDN |
| Multi-framework islands | Svelte for state, Solid for forms | Framework-specific strengths reduce bundle size | Slightly higher build time, lower runtime cost |
| External image sources | <Image> with explicit dimensions | Prevents CLS, enables responsive format negotiation | Minor build overhead, major UX gain |
| Team AI adoption | Centralized .ai-context.md + CI validation | Consistent output, prevents architectural drift | One-time setup, long-term maintenance savings |
Configuration Template
Copy this template into your project root. Adjust values to match your stack.
# AI Context Contract: Astro Architecture Guidelines
## Stack Declaration
- Framework: astro@5.2
- Output Mode: static
- Islands: svelte@5, solid@1.9
- Styling: tailwindcss@4.0
- Runtime: node@22
- TypeScript: strict mode enabled
## Execution Boundaries
- Frontmatter (`---`) runs on SERVER only
- NEVER use window, document, localStorage, or navigator in frontmatter
- Client logic belongs in <script> tags or island components
- Hydration strategy: defer-unless-critical
## API Contracts
- Content: use getCollection() from astro:content
- Images: use <Image> or <Picture> from astro:assets
- Environment: import.meta.env.PUBLIC_* for client, import.meta.env.* for server
- Routing: export getStaticPaths() for static dynamic routes
- Styles: scoped by default, <style is:global> for page-level only
## Validation Gates
- npm run build: verify static output
- npx astro check: type validation
- npx astro build --debug: inspect hydration boundaries
- CI pipeline must pass all gates before merge
Quick Start Guide
- Create the context file: Add
.ai-context.md to your project root and paste the Configuration Template.
- Configure your AI tool: Point your AI assistant to the context file. Most tools auto-detect root markdown files. Verify the model acknowledges the constraints.
- Generate a test component: Prompt the AI to create a dashboard card with dynamic data. Verify it uses
getCollection(), <Image>, and appropriate client: directives.
- Run validation gates: Execute
npm run build && npx astro check. Fix any architectural violations before proceeding.
- Commit and enforce: Add the context file to version control. Configure your CI pipeline to reject PRs that bypass hydration or type checks.
Context-driven AI generation transforms Astro development from experimental to production-ready. By explicitly defining execution boundaries, API contracts, and validation gates, you ensure that AI output aligns with framework architecture rather than generic web patterns. The result is predictable performance, zero architectural drift, and maintainable codebases at scale.