Why Astro for Docs?
Astro ships zero JavaScript by default, which means documentation sites are blazing fast — typically scoring 100 on Core Web Vitals. It supports MDX natively, so you can embed React/Vue/Svelte components inside Markdown.
Content Collections
Astro's Content Collections API gives you type-safe frontmatter validation and automatic routing for all your Markdown articles.
"hl-keyword">import { defineCollection, z } "hl-keyword">from 'astro:content';
"hl-keyword">const blog = defineCollection({
"hl-keyword">type: 'content',
schema: z."hl-type">object({
title: z."hl-type">string(),
description: z."hl-type">string(),
publishedAt: z.coerce.date(),
author: z."hl-type">string(),
tags: z.array(z."hl-type">string()),
draft: z."hl-type">boolean()."hl-keyword">default(false),
}),
});
"hl-keyword">export "hl-keyword">const collections = { blog };
MDX with Live Components
MDX allows you to import and render interactive components directly inside your Markdown content. Perfect for live code playgrounds, interactive diagrams, and embedded demos.
---
title: "My Deep Dive"
publishedAt: 2025-01-30
author: "Vikram Rao"
tags: ["Astro", "MDX"]
---
"hl-keyword">import CodePlayground "hl-keyword">from '../../components/CodePlayground.astro';
"hl-keyword">import Chart "hl-keyword">from '../../components/Chart.tsx';
"hl-keyword">class="hl-comment">## Interactive Example
<CodePlayground code={`const x = 1 + 1; console.log(x);`} />
"hl-keyword">class="hl-comment">## Live Data Chart
<Chart client:visible data={[1, 4, 9, 16, 25]} />
Regular markdown still works, with **bold**, _italic_, and `code`.
Dynamic Routes for Articles
Astro's file-based routing makes it trivial to generate one page per article from your Content Collection.
---
"hl-keyword">import { getCollection } "hl-keyword">from 'astro:content';
"hl-keyword">export "hl-keyword">async "hl-keyword">function getStaticPaths() {
"hl-keyword">const posts = "hl-keyword">await getCollection('blog', ({ data }) => !data.draft);
"hl-keyword">return posts.map(post => ({
params: { slug: post.slug },
props: { post },
}));
}
"hl-keyword">const { post } = Astro.props;
"hl-keyword">const { Content } = "hl-keyword">await post.render();
---
<article>
<h1>{post.data.title}</h1>
<Content />
</article>