back to blog
developmentFebruary 9, 2026 · 3 min read

Astro 5: Content Collections v2 and Server Islands Explained

Astro 5 ships a redesigned Content Layer and a powerful Server Islands feature that brings dynamic personalization to static sites. Here's what changed and why it matters.

Dan Holloran
Dan Holloran
Senior Frontend & Fullstack Developer
Astro 5: Content Collections v2 and Server Islands Explained image

Astro has carved out a clear niche: ship as little JavaScript as possible, use any framework you already know for interactive islands, and make content-heavy sites blazing fast by default. Astro 5 continues this trajectory with two significant additions: a redesigned Content Layer and Server Islands — a pattern that might finally retire the "static vs dynamic" binary for content sites.

Content Layer: A Unified Data API

The original Content Collections API was a great improvement over managing markdown files manually, but it was limited to files in the src/content/ directory. Astro 5's Content Layer removes that constraint. Data can come from local files, remote APIs, CMS platforms, or any custom loader you write:

ts
// astro.config.mjs
import { defineConfig } from "astro/config";
import { glob } from "astro/loaders";

export default defineConfig({
  // Config-level collections (no src/content/ required)
});
ts
// src/content/config.ts
import { defineCollection, z } from "astro:content";
import { glob, file } from "astro/loaders";

const blog = defineCollection({
  // Load from local markdown
  loader: glob({ pattern: "**/*.md", base: "./src/blog" }),
  schema: z.object({
    title: z.string(),
    published: z.date(),
    tags: z.array(z.string()),
  }),
});

const products = defineCollection({
  // Load from a remote API
  loader: async () => {
    const res = await fetch("https://api.example.com/products");
    return res.json();
  },
  schema: z.object({
    id: z.string(),
    name: z.string(),
    price: z.number(),
  }),
});

export const collections = { blog, products };

The schema validation catches data shape mismatches at build time, and TypeScript types are inferred automatically. Whether your data is local markdown or a remote CMS, the access pattern in your components is identical:

astro
---
import { getCollection } from 'astro:content';
const posts = await getCollection('blog');
---

Server Islands: Dynamic in a Static World

Server Islands are the architectural headline of Astro 5. The problem they solve: you have a mostly static page (fast, cacheable, great for CDN) but a few dynamic sections — a personalized recommendation block, a user's cart count, a live inventory number. Previously you'd either:

  • Make the whole page dynamic (killing cache benefits)
  • Hydrate a client component and fetch from the browser (causing a layout shift)

Server Islands let you mark specific components as server-rendered-on-request while the rest of the page stays static:

astro
---
// src/pages/product/[slug].astro
import { getEntry } from 'astro:content';
import RecommendedProducts from '../components/RecommendedProducts.astro';
import CartButton from '../components/CartButton.astro';

const product = await getEntry('products', Astro.params.slug);
---

<!-- This renders at build time — cached by CDN -->
<h1>{product.data.name}</h1>
<p>{product.data.description}</p>
<p>${product.data.price}</p>

<!-- This renders on request, per user — bypasses CDN cache for this island -->
<CartButton server:defer>
  <span slot="fallback">Add to Cart</span>
</CartButton>

<RecommendedProducts productId={product.data.id} server:defer />

The server:defer directive tells Astro to stream a placeholder immediately and then replace it with the server-rendered content asynchronously. The static shell of the page loads instantly from the CDN; the personalized parts fill in shortly after. No client JavaScript required for the server-rendered content itself.

Why This Architecture Is Compelling

Most content sites don't need a fully dynamic React or Vue SPA. They need fast static pages with a handful of personalized components. Astro 5's combination of the Content Layer and Server Islands covers this use case cleanly, without forcing a choice between "fast static" and "dynamic with JavaScript."

If you're building a marketing site, documentation, or content publication that has any personalized elements, Astro 5 is worth a serious look.