diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 762794bb8..8f12705ab 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,10 +9,10 @@ **/index.mdx @IEvangelist @davidfowl @maddymontaquila # Pipelines and deployment (GitHub Actions workflows) -.github/workflows/** @IEvangelist @captainsafia -/src/frontend/src/content/docs/get-started/pipelines.mdx @IEvangelist @captainsafia -/src/frontend/src/content/docs/get-started/deploy-first-app.mdx @IEvangelist @captainsafia -/src/frontend/src/content/docs/architecture/resource-publishing.mdx @IEvangelist @captainsafia +.github/workflows/** @IEvangelist +/src/frontend/src/content/docs/get-started/pipelines.mdx @IEvangelist +/src/frontend/src/content/docs/get-started/deploy-first-app.mdx @IEvangelist +/src/frontend/src/content/docs/architecture/resource-publishing.mdx @IEvangelist # Dashboard content /src/frontend/src/content/docs/dashboard/** @IEvangelist @JamesNK @@ -21,7 +21,7 @@ /src/frontend/src/content/docs/integrations/** @IEvangelist @eerhardt # Compute integrations -/src/frontend/src/content/docs/integrations/compute/** @IEvangelist @captainsafia +/src/frontend/src/content/docs/integrations/compute/** @IEvangelist # Community content (community-toolkit) /src/frontend/src/content/docs/community/** @IEvangelist @aaronpowell diff --git a/.github/agents/release-verifier.agent.md b/.github/agents/release-verifier.agent.md new file mode 100644 index 000000000..a038ecd1e --- /dev/null +++ b/.github/agents/release-verifier.agent.md @@ -0,0 +1,303 @@ +--- +description: 'Verifies that a release branch is ready for publication by validating the build, site content, whats-new entry, version references, and integration docs.' +tools: ['read/terminalSelection', 'read/terminalLastCommand', 'read/problems', 'read/readFile', 'search', 'web', 'todo', 'terminal'] +name: Release Verifier +--- + +You are an agent responsible for verifying that a `release/*` branch of the aspire.dev documentation site is complete and ready for publication. You coordinate multiple skills — **doc-tester**, **hex1b**, **playwright-cli**, and **update-integrations** — to perform a comprehensive pre-release validation. + +## Inputs + +When invoked you must be told (or derive from the current Git branch) the **release version**. The branch name follows the pattern `release/X.Y` (e.g., `release/13.2`). From the branch name derive: + +| Token | Example | Description | +|-------|---------|-------------| +| `MAJOR` | `13` | Major version number | +| `MINOR` | `2` | Minor version number (may be `0`) | +| `VERSION` | `13.2` | Full display version (`MAJOR.MINOR`) | +| `VERSION_SLUG` | `aspire-13-2` | Slug used in file names and URLs | +| `NUGET_VERSION` | `13.2.0` | NuGet package version (append `.0` when the version is `MAJOR.MINOR`) | + +If no branch or version is explicitly provided, detect it: + +```bash +git branch --show-current +``` + +If the branch does not match `release/*`, stop and ask the user which release version to verify. + +--- + +## Verification plan + +Execute every phase below **in order**. Mark each phase as a todo item so progress is visible. If a phase fails, log the failure, continue with subsequent phases, and include all failures in the final report. + +### Phase 0 — Environment setup + +1. Ensure you are on the correct release branch and the working tree is clean (`git status`). +2. Install frontend dependencies: + + ```bash + pnpm i + ``` + +3. Verify required tools are available: + - `pnpm` (for build / preview) + - `playwright-cli` (for site verification) — see the **playwright-cli** skill + - `dotnet hex1b` (for terminal automation) — see the **hex1b** skill + +### Phase 1 — Clean build + +A clean build **must succeed** with zero errors (this takes several minutes to build). + +```bash +pnpm build +``` + +- If the build fails, capture the full error output and include it in the report. +- If the build succeeds, record the elapsed time and confirm no warnings that indicate missing content or broken references. + +### Phase 2 — Preview server + +Start `pnpm preview` as a background process so the site can be tested with Playwright. + +```bash +pnpm preview +``` + +Record the local URL (typically `http://localhost:4321`). Use the **hex1b** skill to launch the process and wait for the "ready" message if needed. + +### Phase 3 — What's-new entry + +Verify a what's-new page exists for the release version. + +#### 3a. File existence + +Check that the file exists: + +``` +src/frontend/src/content/docs/whats-new/{VERSION_SLUG}.mdx +``` + +For example, for release `13.2` the file is `aspire-13-2.mdx`. If the file does not exist, flag this as a **critical** failure. + +#### 3b. Frontmatter validation + +Read the file and verify: + +| Field | Expected value | +|-------|---------------| +| `title` | Contains the version string (e.g., `What's new in Aspire 13.2`) | +| `sidebar.label` | `Aspire {VERSION}` (e.g., `Aspire 13.2`) | +| `sidebar.order` | Is `0` (newest release should be first) | + +#### 3c. Content checks + +- The page should contain an **upgrade section** (heading containing "Upgrade") with instructions for upgrading to this version. +- NuGet version references in upgrade instructions should use `{NUGET_VERSION}` (e.g., `13.2.0`). +- The page should mention the corresponding .NET SDK requirement if the major version changed. + +#### 3d. Browser verification (Playwright) + +Using the **playwright-cli** skill, navigate to the preview site's what's-new page and verify: + +```bash +playwright-cli open http://localhost:4321/whats-new/{VERSION_SLUG}/ +playwright-cli snapshot +``` + +- Confirm the page renders without errors. +- Confirm the sidebar lists the new release as the first entry under "What's new". + +#### 3e. Previous release sidebar order + +If a previous what's-new entry existed (e.g., `aspire-13-1.mdx` when verifying `13.2`), verify its `sidebar.order` has been incremented so the new release appears first. + +### Phase 4 — Version references audit + +Scan the documentation for version strings that should have been updated for this release. This catches stale references that still point to a prior version. + +#### 4a. Identify the prior version + +Determine the immediately prior version. For `13.2` the prior is `13.1`; for `13.0` the prior is `9.5` (or whatever the last release of the previous major is). Use the existing what's-new files to determine this. + +#### 4b. Scan for stale version references + +Search the docs content tree for references to the prior NuGet version that appear **outside** of intentional historical context (e.g., upgrade-from examples that deliberately show the old version). + +```bash +# Search for prior version references +grep -rn "{PRIOR_NUGET_VERSION}" src/frontend/src/content/docs/ \ + --include="*.mdx" \ + --exclude-dir="whats-new" +``` + +Also search for stale SDK version references: + +```bash +grep -rn 'Aspire.AppHost.Sdk.*Version="{PRIOR_NUGET_VERSION}"' src/frontend/src/content/docs/ \ + --include="*.mdx" +``` + +#### 4c. Evaluate each match + +For every match found: + +1. **Read the surrounding context** (at least 10 lines before and after). +2. **Classify the reference**: + - **Intentional (old-version example)**: The reference is inside a "before" / upgrade-from code block that deliberately shows the old version to contrast with the new version. These are acceptable — do **not** flag them. + - **Stale (should be updated)**: The reference is in current guidance, installation instructions, or sample code that a user would copy today. Flag these for update. +3. Log each stale reference with file path, line number, and surrounding context. + +#### 4d. Verify new version references + +Spot-check that key documentation pages reference the release version: + +| Page | What to check | +|------|---------------| +| `get-started/install-cli` or equivalent | CLI install commands reference the current release | +| `get-started/first-app` or equivalent | Sample project uses current SDK version | +| `whats-new/upgrade-aspire.mdx` | Upgrade matrix includes the new version | + +### Phase 5 — Integration docs sync + +Run the **update-integrations** skill to ensure integration documentation links are current. + +1. Run the update script: + + ```bash + cd src/frontend && node scripts/update-integrations.js + ``` + +2. Check for uncommitted changes in `src/frontend/src/data/aspire-integrations.json` and `src/frontend/src/data/integration-docs.json`. If there are changes, flag them — integration data should have been committed before release. + +3. Verify no stale entries exist (packages removed from NuGet but still listed) and no new packages are unmapped. + +### Phase 6 — Site-wide smoke test (Playwright) + +Using the **playwright-cli** skill, perform a quick smoke test of the preview site. + +```bash +playwright-cli open http://localhost:4321 +``` + +#### 6a. Landing page + +- Navigate to the root URL. +- Take a snapshot and confirm the page renders. +- Verify the hero or banner references the current release version (if applicable). + +#### 6b. Navigation spot-checks + +Navigate to each top-level section and confirm pages load: + +| Path | Check | +|------|-------| +| `/get-started/` | Page renders, links work | +| `/fundamentals/` | Page renders | +| `/integrations/` | Integration gallery loads | +| `/whats-new/` | Lists current release first | +| `/deployment/` | Page renders | +| `/reference/` | Page renders | + +#### 6c. What's-new page rendering + +Navigate to `/whats-new/{VERSION_SLUG}/` and: + +- Confirm all headings render correctly (snapshot). +- Confirm code blocks are syntax-highlighted. +- Confirm images load (no broken image placeholders). +- Click at least two internal links and verify they resolve. + +### Phase 7 — Cleanup + +1. Stop the preview server (kill the background process). +2. Close any Playwright browser sessions: + + ```bash + playwright-cli close + ``` + +3. Stop any hex1b terminal sessions. + +--- + +## Report format + +After all phases are complete, produce a structured report: + +```markdown +# Release Verification Report + +**Branch:** release/{VERSION} +**Date:** {ISO date} +**Agent:** release-verifier + +## Summary + +| Phase | Status | Details | +|-------|--------|---------| +| 0 — Environment setup | ✅ / ❌ | ... | +| 1 — Clean build | ✅ / ❌ | ... | +| 2 — Preview server | ✅ / ❌ | ... | +| 3 — What's-new entry | ✅ / ❌ | ... | +| 4 — Version references | ✅ / ⚠️ / ❌ | ... | +| 5 — Integration docs | ✅ / ⚠️ / ❌ | ... | +| 6 — Smoke test | ✅ / ❌ | ... | +| 7 — Cleanup | ✅ / ❌ | ... | + +## Critical issues + +[Issues that must be fixed before release] + +### Issue N: [Title] + +**Phase:** N +**Severity:** Critical / High / Medium +**File:** [path with line number] +**Description:** ... +**Recommended fix:** ... + +## Warnings + +[Issues that should be reviewed but may be acceptable] + +## Stale version references + +| File | Line | Context | Classification | +|------|------|---------|---------------| +| ... | ... | ... | Stale / Intentional | + +## Integration docs status + +- Packages in catalog: N +- Mapped entries: N +- New mappings needed: [list] +- Stale mappings removed: [list] +- Unmapped packages: [list] + +## Passed checks + +[Brief list of everything that passed] +``` + +--- + +## Failure handling + +- **Build failure (Phase 1)**: This is a blocking failure. Log the error and continue with remaining phases to gather as much information as possible, but mark the overall verification as **FAILED**. +- **Missing what's-new file (Phase 3a)**: Critical failure. Document it and continue. +- **Stale version references (Phase 4)**: Flag each one with its classification. This is a **warning** unless the stale reference appears in user-facing installation or getting-started instructions, in which case it is **critical**. +- **Integration docs out of sync (Phase 5)**: Warning unless packages are completely unmapped. +- **Smoke test failures (Phase 6)**: Critical if pages fail to render; warning if only cosmetic issues. + +## Skills reference + +This agent depends on the following skills. Read the full skill instructions before using them: + +| Skill | File | When used | +|-------|------|-----------| +| doc-tester | `.github/skills/doc-tester/SKILL.md` | Phase 3 (content validation), Phase 6 (smoke test) | +| hex1b | `.github/skills/hex1b/SKILL.md` | Phase 2 (preview server management), terminal capture | +| playwright-cli | `.github/skills/playwright-cli/SKILL.md` | Phase 3d, Phase 6 (browser-based verification) | +| update-integrations | `.github/skills/update-integrations/SKILL.md` | Phase 5 (integration docs sync) | diff --git a/.github/astro.instructions.md b/.github/astro.instructions.md index 3d5f64646..da81a3874 100644 --- a/.github/astro.instructions.md +++ b/.github/astro.instructions.md @@ -1,214 +1,285 @@ --- -description: 'Astro development standards and best practices for content-driven websites' +description: 'Astro Starlight development standards for aspire.dev documentation site' applyTo: '**/*.astro, **/*.ts, **/*.js, **/*.md, **/*.mdx' --- -# Astro Development Instructions - -Instructions for building high-quality Astro applications following the content-driven, server-first architecture with modern best practices. - -## Project Context -- Astro 5.x with Islands Architecture and Content Layer API -- TypeScript for type safety and better DX with auto-generated types -- Content-driven websites (blogs, marketing, e-commerce, documentation) -- Server-first rendering with selective client-side hydration -- Support for multiple UI frameworks (React, Vue, Svelte, Solid, etc.) -- Static site generation (SSG) by default with optional server-side rendering (SSR) -- Enhanced performance with modern content loading and build optimizations - -## Development Standards - -### Architecture -- Embrace the Islands Architecture: server-render by default, hydrate selectively -- Organize content with Content Collections for type-safe Markdown/MDX management -- Structure projects by feature or content type for scalability -- Use component-based architecture with clear separation of concerns -- Implement progressive enhancement patterns -- Follow Multi-Page App (MPA) approach over Single-Page App (SPA) patterns - -### TypeScript Integration -- Configure `tsconfig.json` with recommended v5.0 settings: -```json -{ - "extends": "astro/tsconfigs/base", - "include": [".astro/types.d.ts", "**/*"], - "exclude": ["dist"] -} +# aspire.dev Development Instructions + +This is the aspire.dev documentation site, built with [Astro Starlight](https://starlight.astro.build/). All source lives under `src/frontend/`. + +## Project Stack + +- **Astro 5.x** with **Starlight** documentation theme +- **TypeScript** (strict mode, `astro/tsconfigs/strict`) +- **Static site generation** (SSG) — zero client-side JS by default +- **pnpm** as the package manager (`pnpm install`, `pnpm dev`, `pnpm build`) +- **15 locales** with Lunaria translation tracking + +## Running Locally + +```bash +cd src/frontend +pnpm install +pnpm dev # starts dev server at http://localhost:4321 +``` + +Search is disabled in dev mode — use `pnpm build && pnpm preview` to test search. Running `pnpm dev` is sufficient to verify documentation rendering changes; a full `pnpm build` is not required. + +## Project Structure + +``` +src/frontend/ +├── astro.config.mjs # Starlight config, plugins, integrations +├── ec.config.mjs # Expressive Code config (themes, plugins) +├── tsconfig.json # TypeScript config with path aliases +├── config/ # Sidebar topics, locales, redirects, cookies, SEO head +│ └── sidebar/ # Sidebar topic modules (7 files) +├── src/ +│ ├── content.config.ts # Content collections (docs, i18n, packages) +│ ├── route-data-middleware.ts +│ ├── assets/ # Images, icons, logos +│ ├── components/ # Custom Astro components +│ │ └── starlight/ # Starlight component overrides +│ ├── content/docs/ # All documentation pages (MDX/MD) +│ ├── data/ # JSON data files + pkgs/ API reference +│ ├── expressive-code-plugins/ # Custom EC plugins (disable-copy) +│ ├── pages/ # Astro page routes +│ ├── styles/ # Global CSS (site.css) +│ └── utils/ # Helpers, package utils, sample tags +``` + +## Import Aliases + +Always use these path aliases (defined in `tsconfig.json`) instead of relative paths: + +| Alias | Resolves to | +|---|---| +| `@assets/*` | `./src/assets/*` | +| `@components/*` | `./src/components/*` | +| `@data/*` | `./src/data/*` | +| `@utils/*` | `./src/utils/*` | + +Example usage in MDX frontmatter imports: + +```mdx +import LearnMore from '@components/LearnMore.astro'; +import ThemeImage from '@components/ThemeImage.astro'; +import { Aside, Code, Steps, LinkButton, Tabs, TabItem } from '@astrojs/starlight/components'; +``` + +## Starlight Plugins + +The site uses these Starlight plugins (configured in `astro.config.mjs`): + +| Plugin | Purpose | +|---|---| +| `starlight-sidebar-topics` | Dynamic sidebar organized by topic areas | +| `starlight-page-actions` | Share + AI action buttons (Copilot, Claude, ChatGPT) | +| `starlight-image-zoom` | Click-to-zoom images with captions | +| `starlight-kbd` | OS-aware keyboard shortcut display | +| `starlight-github-alerts` | GitHub-style `> [!NOTE]` callout syntax | +| `starlight-links-validator` | Build-time link checking | +| `starlight-scroll-to-top` | Scroll-to-top button | +| `starlight-llms-txt` | AI training data formatting | +| `@lunariajs/starlight` | i18n translation dashboard | +| `@catppuccin/starlight` | Theme integration | +| `astro-mermaid` | Mermaid diagram rendering | + +## Starlight Component Overrides + +Custom overrides live in `src/components/starlight/` and are registered in `astro.config.mjs` under `components:`: + +- `EditLink.astro` — adds translation link +- `Footer.astro` — custom 4-column footer layout +- `Head.astro` — git metadata, auto-language detection, accessibility +- `Header.astro` — custom nav with cookie/CLI buttons +- `Hero.astro` — enhanced hero with image variants +- `MarkdownContent.astro` — image zoom wrapper +- `Search.astro` — search with API docs notice +- `Sidebar.astro` — enhanced sidebar with API filter & collapse +- `SocialIcons.astro` — additional social/misc buttons + +When modifying these, study the corresponding Starlight source component to understand the expected props and slots. + +## Custom Components + +Many reusable components exist in `src/components/`. Before creating a new component, check what already exists. Key categories: + +- **Layout/UI**: `HeroSection`, `TopicHero`, `IconLinkCard`, `MediaCard`, `SimpleCard`, `FluidGrid`, `Pivot`, `Expand` +- **Integrations**: `IntegrationCard`, `IntegrationGrid`, `Integrations`, `IntegrationTotals` +- **Media**: `LoopingImage`, `LoopingVideo`, `VimeoCard`, `YouTubeCard`, `TerminalShowcase` +- **Content helpers**: `Include`, `Placeholder`, `InstallAspireCLI`, `CodespacesButton`, `LearnMore` +- **Interactive**: `OsAwareTabs`, `AppHostBuilder`, `QuickStartJourney`, `TestimonialCarousel` +- **API reference**: `TypeHero`, `TypeSignature`, `MemberCard`, `MemberList`, `EnumTable`, `InheritanceDiagram` + +Always follow existing component patterns: `.astro` files with frontmatter props at top, scoped styles, and PascalCase naming. + +## Content Collections + +Defined in `src/content.config.ts`: + +- **docs** — uses Starlight's docs loader with extended schema fields: `renderBlocking`, `giscus`, `category`, `pageActions` +- **i18n** — Starlight i18n loader for 15 locales +- **packages** — auto-generated API reference JSON from `src/data/pkgs/` + +## Writing Documentation (MDX) + +### Frontmatter + +Every page needs at minimum a `title`. Custom fields include: + +```yaml +--- +title: My page title +category: conceptual # conceptual | quickstart | tutorial | blog | reference | sample +giscus: true # enable comments +pageActions: false # disable AI/share actions +--- ``` -- Types auto-generated in `.astro/types.d.ts` (replaces `src/env.d.ts`) -- Run `astro sync` to generate/update type definitions -- Define component props with TypeScript interfaces -- Leverage auto-generated types for content collections and Content Layer API - -### Component Design -- Use `.astro` components for static, server-rendered content -- Import framework components (React, Vue, Svelte) only when interactivity is needed -- Follow Astro's component script structure: frontmatter at top, template below -- Use meaningful component names following PascalCase convention -- Keep components focused and composable -- Implement proper prop validation and default values - -### Content Collections - -#### Modern Content Layer API (v5.0+) -- Define collections in `src/content.config.ts` using the new Content Layer API -- Use built-in loaders: `glob()` for file-based content, `file()` for single files -- Leverage enhanced performance and scalability with the new loading system -- Example with Content Layer API: -```typescript -import { defineCollection, z } from 'astro:content'; -import { glob } from 'astro/loaders'; - -const blog = defineCollection({ - loader: glob({ pattern: '**/*.md', base: './src/content/blog' }), - schema: z.object({ - title: z.string(), - pubDate: z.date(), - tags: z.array(z.string()).optional() - }) -}); + +### Key Conventions + +- **Heading 1 is reserved** for the page title from frontmatter — start content headings at `##` +- **Use sentence case** for all headings and sidebar labels +- **Use active voice** and clear, concise language +- **Site-relative links** must include a trailing slash: `[First app](/get-started/first-app/)` +- **Unordered lists** use `-` (not `*`) +- **Italic text** uses `_` (not `*`) +- **Code blocks** use triple backticks with language identifier and optional `title`: + ````md + ```csharp title="Program.cs" + var builder = DistributedApplication.CreateBuilder(args); + ``` + ```` + +### Starlight Components in MDX + +Import from `@astrojs/starlight/components`: + +```mdx +import { Aside, Code, Steps, LinkButton, Tabs, TabItem } from '@astrojs/starlight/components'; ``` -#### Legacy Collections (backward compatible) -- Legacy `type: 'content'` collections still supported via automatic glob() implementation -- Migrate existing collections by adding explicit `loader` configuration -- Use type-safe queries with `getCollection()` and `getEntry()` -- Structure content with frontmatter validation and auto-generated types - -### View Transitions & Client-Side Routing -- Enable with `` component in layout head (renamed from `` in v5.0) -- Import from `astro:transitions`: `import { ClientRouter } from 'astro:transitions'` -- Provides SPA-like navigation without full page reloads -- Customize transition animations with CSS and view-transition-name -- Maintain state across page navigations with persistent islands -- Use `transition:persist` directive to preserve component state - -### Performance Optimization -- Default to zero JavaScript - only add interactivity where needed -- Use client directives strategically (`client:load`, `client:idle`, `client:visible`) -- Implement lazy loading for images and components -- Optimize static assets with Astro's built-in optimization -- Leverage Content Layer API for faster content loading and builds -- Minimize bundle size by avoiding unnecessary client-side JavaScript - -### Styling -- Use scoped styles in `.astro` components by default -- Implement CSS preprocessing (Sass, Less) when needed -- Use CSS custom properties for theming and design systems -- Follow mobile-first responsive design principles -- Ensure accessibility with semantic HTML and proper ARIA attributes -- Consider utility-first frameworks (Tailwind CSS) for rapid development - -### Client-Side Interactivity -- Use framework components (React, Vue, Svelte) for interactive elements -- Choose the right hydration strategy based on user interaction patterns -- Implement state management within framework boundaries -- Handle client-side routing carefully to maintain MPA benefits -- Use Web Components for framework-agnostic interactivity -- Share state between islands using stores or custom events - -### API Routes and SSR -- Create API routes in `src/pages/api/` for dynamic functionality -- Use proper HTTP methods and status codes -- Implement request validation and error handling -- Enable SSR mode for dynamic content requirements -- Use middleware for authentication and request processing -- Handle environment variables securely - -### SEO and Meta Management -- Use Astro's built-in SEO components and meta tag management -- Implement proper Open Graph and Twitter Card metadata -- Generate sitemaps automatically for better search indexing -- Use semantic HTML structure for better accessibility and SEO -- Implement structured data (JSON-LD) for rich snippets -- Optimize page titles and descriptions for search engines - -### Inclusive and Accessible Content - -#### Writing with Inclusivity -- **Use inclusive language**: Respect all readers regardless of ability, background, identity, or experience level -- **People-first language**: Say "person who uses a screen reader" not "blind user" -- **Avoid assumptions**: Don't use phrases like "as you can see" or "simply click" -- **No ableist language**: Avoid terms like "blind to," "crippled by," "crazy," "insane," "lame" -- **Gender-neutral language**: Use "they/them" or rewrite to avoid gendered pronouns -- **Global perspective**: Avoid idioms, colloquialisms, and culturally-specific references - -#### Plain Language Principles -- **Write short sentences**: Aim for 15-20 words conveying one main idea -- **Use common words**: Avoid jargon or define technical terms on first use -- **Active voice**: Prefer "The system processes" over "is processed by" -- **Break up text**: Keep paragraphs to 3-5 sentences -- **Descriptive headings**: Make section purposes clear for scanning - -#### Accessible Content Structure -- **Proper heading hierarchy**: Use H1 → H2 → H3 without skipping levels -- **One H1 per page**: Establish clear document hierarchy -- **Meaningful link text**: Use "Read the deployment guide" not "Click here" -- **Alt text for images**: Describe informative images, use `alt=""` for decorative ones -- **Lists for structure**: Use bulleted/numbered lists to break up dense text -- **Table headers**: Always include `` elements for column and row headers - -#### Global and Cultural Considerations -- **Universal dates**: Write "January 15, 2025" not "1/15/25" -- **Time zones**: Specify zones when referencing specific times -- **Measurements**: Use metric alongside imperial when relevant -- **Diverse examples**: Use varied names and scenarios reflecting global audiences -- **Avoid stereotypes**: Represent different contexts and industries in examples - -### Image Optimization -- Use Astro's `` component for automatic optimization -- Implement responsive images with proper srcset generation -- Use WebP and AVIF formats for modern browsers -- Lazy load images below the fold -- Provide proper alt text for accessibility -- Optimize images at build time for better performance - -### Data Fetching -- Fetch data at build time in component frontmatter -- Use dynamic imports for conditional data loading -- Implement proper error handling for external API calls -- Cache expensive operations during build process -- Use Astro's built-in fetch with automatic TypeScript inference -- Handle loading states and fallbacks appropriately - -### Build & Deployment -- Optimize static assets with Astro's built-in optimizations -- Configure deployment for static (SSG) or hybrid (SSR) rendering -- Use environment variables for configuration management -- Enable compression and caching for production builds - -## Key Astro v5.0 Updates - -### Breaking Changes -- **ClientRouter**: Use `` instead of `` -- **TypeScript**: Auto-generated types in `.astro/types.d.ts` (run `astro sync`) -- **Content Layer API**: New `glob()` and `file()` loaders for enhanced performance - -### Migration Example -```typescript -// Modern Content Layer API -import { defineCollection, z } from 'astro:content'; -import { glob } from 'astro/loaders'; - -const blog = defineCollection({ - loader: glob({ pattern: '**/*.md', base: './src/content/blog' }), - schema: z.object({ title: z.string(), pubDate: z.date() }) -}); +- **`