Astro Framework Guide
Astro Component
---
// Frontmatter — runs at build/request time
import Layout from '../layouts/Layout.astro';
const { title } = Astro.props;
const posts = await fetch('/api/posts').then(r => r.json());
---
<Layout title={title}>
<h1>{title}</h1>
<ul>
{posts.map(p => <li><a href={p.url}>{p.title}</a></li>)}
</ul>
</Layout>
Island Architecture (Partial Hydration)
<!-- Hydration directives -->
<ReactCounter client:load /> <!-- hydrate immediately -->
<ReactCounter client:idle /> <!-- when idle -->
<ReactCounter client:visible /> <!-- when in viewport -->
<ReactCounter client:media="(max-width: 768px)" />
<ReactCounter client:only="react" /> <!-- SSR-skipped -->
Content Collections
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
date: z.date(),
tags: z.array(z.string()).optional(),
}),
});
export const collections = { blog };
// Use in a page
import { getCollection } from 'astro:content';
const posts = await getCollection('blog');
const sorted = posts.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
Routing
src/pages/
├── index.astro # /
├── about.astro # /about
├── blog/
│ ├── index.astro # /blog
│ └── [slug].astro # /blog/:slug (dynamic)
└── api/
└── users.ts # /api/users (API endpoint)
# Dynamic route
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(p => ({ params: { slug: p.slug } }));
}