Instructions for AI agents working on this codebase.
Never use npm, yarn, or pnpm. Always use bun.
# Correct
bun install
bun run dev
bun run build
bun add package-name
# Wrong - do not use
npm install
npm run dev
yarn add package-nameBefore completing any page modification, verify:
- Page has unique
titleanddescriptionin content object - JSON-LD structured data is present (use
src/lib/ldJson.tshelpers) - All images have descriptive
alttext - Headings follow proper hierarchy (h1 > h2 > h3)
- Blog posts include article OG tags (
ogType,articlePublishedTime, etc.)
Before completing any component modification, verify:
- All interactive elements are keyboard accessible
- Decorative SVGs have
aria-hidden="true" - Form inputs have labels or
aria-label - Dynamic content uses
aria-liveregions - Focus states are visible
- Icon-only buttons have
aria-label
- Create page in
src/pages/ - Import Layout and ldJson helpers
- Define title, description, and structured data
- Pass content object to Layout
Example:
---
import Layout from '@/layouts/Layout.astro'
import { createServiceLdJson, createLdJsonGraph } from '@/lib/ldJson'
const title = 'Page Title | Capgo'
const description = 'Page description for SEO'
const serviceLdJson = createServiceLdJson(Astro.locals.runtimeConfig.public, {
name: title,
description,
url: Astro.url.href,
serviceType: 'Software Development Service',
areaServed: ['Worldwide'],
})
const ldJSON = createLdJsonGraph(Astro.locals.runtimeConfig.public, serviceLdJson, {
includeOrganization: true,
})
const content = { title, description, ldJSON }
---
<Layout content={content}>
<!-- Page content -->
</Layout>Always add accessibility attributes:
<!-- Decorative icon (hidden from screen readers) -->
<svg aria-hidden="true" class="...">...</svg>
<!-- Meaningful icon (needs label) -->
<div role="img" aria-label="Description of icon">
<svg aria-hidden="true">...</svg>
</div>Always include labels:
<!-- With visible label -->
<label for="email">Email</label>
<input id="email" type="email" />
<!-- With aria-label (no visible label) -->
<input type="search" aria-label="Search plugins" />After making changes:
- Run
bun run buildto check for build errors - Validate structured data at https://search.google.com/test/rich-results
- Test keyboard navigation (Tab, Enter, Escape)
- Check color contrast and focus visibility