Astro Skill
Reference for building static Astro sites (output: 'static'). Covers architecture decisions, content collections, SEO, image optimization, pagination, and deployment patterns.
Consult docs.astro.build and llms.txt for latest APIs when needed.
References
Read these files for detailed patterns and templates:
| Reference | What it covers |
|---|---|
content-collections.md |
Schemas (z.image, z.enum, reference()), querying, dynamic routes, entry.body |
image-optimizations.md |
<Image /> component, downscaling tip, SVG components, aspect ratios |
seo-checklist.md |
Head component, per-page checklist, structured data (JSON-LD), hreflang, content rules |
pagination.md |
paginate(), nested pagination, page prop |
Architecture Rules
1. Astro-first
.astrofiles for everything presentational — zero JS shipped to client.- Framework components (
.tsx,.svelte,.vue, etc.) only when interactivity is needed.
2. Minimal hydration
Use the lightest client:* directive that works:
| Directive | Use case |
|---|---|
client:load |
Critical above-the-fold interactivity |
client:idle |
Non-critical (modals, popovers) |
client:visible |
Below-the-fold widgets |
client:media |
Screen-size-specific UI (e.g. mobile sidebar toggle) |
client:only="<framework>" |
Browser-only APIs (e.g. localStorage, WebGL) |
3. Keep islands small
- Wrap only the interactive subtree in a framework component. Surrounding static markup stays in
.astro. - Pass data via props from the
.astroparent — never refetch inside islands.
4. Fonts via Fontsource
Always install fonts locally via Fontsource npm packages — never Google Fonts CDN links.
Example if using Inter
npm install @fontsource-variable/inter
Key Patterns
Layout & Head
Use src/layouts/Layout.astro as the base layout. Import with @/layouts/Layout.astro.
Use src/components/Head.astro for SEO meta tags, Open Graph, Twitter Cards, canonical URLs, and JSON-LD structured data. Import it inside your layout — see seo-checklist.md for the full component and per-page checklist.
Sitemap
Always include @astrojs/sitemap — it auto-generates sitemap-index.xml at build time. Install and add it to integrations in astro.config.mjs:
npx astro add sitemap
Exclude admin pages, API routes, and utility pages from the sitemap.
robots.txt
Create src/pages/robots.txt.ts — Astro will build it into a static robots.txt file at the site root. It dynamically references the sitemap URL using Astro.site:
import type { APIRoute } from 'astro';
const getRobotsTxt = (sitemapURL: URL) => `\
User-agent: *
Allow: /
Sitemap: ${sitemapURL.href}
`;
export const GET: APIRoute = ({ site }) => {
const sitemapURL = new URL('sitemap-index.xml', site);
return new Response(getRobotsTxt(sitemapURL));
};
This requires site to be set in astro.config.mjs so the sitemap URL resolves correctly.
Image optimization
Always use <Image /> from astro:assets — not <img> tags. Set explicit width/height to downscale large source images (e.g., 10000×10000 → 1024×1024 = smaller WebP output).
Content collections (v5+)
- Config at
src/content.config.ts(NOTsrc/content/config.ts) - Every collection needs a
loader(useglobfromastro/loaders) - Use
z.image()for validated, optimized image fields - Use
z.enum()for constrained values instead of booleans - Use
reference()for relations between collections
Static output
- Always use
output: 'static'(the default) — all pages are pre-rendered to HTML at build time. - Do NOT use
output: 'hybrid'— removed in Astro v5. - Do NOT use
output: 'server'or SSR adapters.
Trailing slashes
- Set
trailingSlash: 'always'inastro.config.mjsto enforce trailing slashes on all generated URLs. - Always use trailing slashes in internal links (
/about/not/about) to avoid duplicate content issues.