Astro Basics for Content Sites
Astro excels at content-heavy sites. It was designed from the ground up for blogs, documentation, and marketing pages. Here’s a deep dive into what makes it special.
The Content-First Philosophy
Most frameworks assume you’re building an app. Astro assumes you’re building a website. The difference matters.
Apps need:
- Client-side routing
- State management
- Real-time updates
- Heavy interactivity
Content sites need:
- Fast initial load
- Great SEO
- Simple deployment
- Minimal maintenance
Astro optimizes for the latter. By default, it outputs static HTML. No JavaScript is sent to the client unless you explicitly add it.
Content Collections
Content lives in src/content/ with type-safe schemas. Each collection defines its frontmatter shape using Zod:
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
pubDate: z.coerce.date(),
tags: z.array(z.string()).default([]),
}),
});
Benefits:
- Autocomplete in your editor
- Validation at build time
- Type safety when querying
- Clear errors when frontmatter is invalid
You query with getCollection() or getEntry(). The API is designed for content, not generic data.
Zero JS by Default
Astro ships zero JavaScript unless you opt in. This isn’t a limitation—it’s a feature.
When you need interactivity, use the client:* directives:
client:load— Hydrate on page loadclient:idle— Hydrate when the browser is idleclient:visible— Hydrate when the component enters the viewportclient:media— Hydrate based on a media query
Only the components you hydrate receive JavaScript. The rest stay as static HTML.
Islands Architecture
The “islands” metaphor: your page is mostly static HTML, with small islands of interactivity.
A typical blog might have:
- Static — Header, footer, article content, sidebar
- Island — Comment widget (React/Vue/Svelte)
- Island — Theme toggle (minimal JS)
- Island — Search (when the user focuses the input)
Each island loads independently. A comment widget doesn’t block the rest of the page. You get the performance of static with the interactivity of a framework where it matters.
MDX Support
Want to embed React components in your Markdown? Use MDX. Astro has first-class support:
---
title: My Post
---
import Chart from '../components/Chart.astro';
Here's a chart:
<Chart data={[1, 2, 3]} />
You can create custom components for callouts, embeds, or interactive demos. The rest of your content stays in familiar Markdown.
File-Based Routing
Pages live in src/pages/. The file structure maps to URLs:
src/pages/index.astro→/src/pages/about.astro→/aboutsrc/pages/blog/[...slug].astro→/blog/*
Dynamic routes use getStaticPaths() for static generation. No server required.
Built-In Optimizations
Astro handles a lot for you:
- Image optimization — Resizing, format conversion, lazy loading
- CSS — Scoped by default, minimal duplication
- View Transitions — Smooth page changes with one component
- Partial hydration — Only what you need
When to Choose Astro
Astro is ideal for:
- Blogs and documentation
- Marketing sites
- Portfolios
- Content-heavy applications
Consider something else if you need:
- Full client-side routing with complex state
- Real-time collaboration
- Heavy server-side logic on every request
Astro’s content-first approach means you spend less time configuring and more time writing. Give it a try for your next content project.