Server Islands
The problem server islands solve
Section titled “The problem server islands solve”Client islands are about client-side interactivity. Server islands solve a different problem: a page that is mostly cacheable and static, but has one part that is personalized or slow — the logged-in user’s avatar, a “recommended for you” strip, a live price that needs a fresh query.
Without server islands you’re forced to choose: render the whole page on demand (losing the cache on the 95% that never changes), or give up the personalized part. Server islands let you have both — cache the shell, defer the dynamic bit.
server:defer
Section titled “server:defer”Add the server:defer directive to any .astro component to turn it into a server island. Astro then renders the rest of the page immediately — without waiting for that component — and the deferred component’s real HTML is fetched separately and swapped in when ready.
---import Avatar from '../components/Avatar.astro';---<Avatar server:defer />The page’s initial HTML ships right away and can be cached at the edge. The Avatar renders on the server — so it can safely read cookies, a session, or a database — but out of band, on its own request, after the shell is already on screen.
Fallback content with slot="fallback"
Section titled “Fallback content with slot="fallback"”Because the real content arrives a moment later, you provide fallback content to show in the meantime — a skeleton, a spinner, or a generic placeholder — using slot="fallback":
---import Avatar from '../components/Avatar.astro';import GenericAvatar from '../components/GenericAvatar.astro';---<Avatar server:defer> <GenericAvatar slot="fallback" /></Avatar>The GenericAvatar renders into the cached shell immediately; the personalized Avatar replaces it once its own server render returns.
flowchart TB req["request the page"] --> shell["server renders shell instantly (cacheable)"] shell --> fb["fallback shown in place of the island"] fb --> fetch["browser fetches the deferred island"] fetch --> srv["island renders on the server (cookies, session, db)"] srv --> swap["real HTML swapped in over the fallback"]
When to use them (and the adapter requirement)
Section titled “When to use them (and the adapter requirement)”Server islands are the right tool when a page is cacheable except for a small dynamic piece:
- A marketing or product page that’s identical for everyone except a personalized greeting or cart.
- A mostly-static page with one slow query you don’t want blocking first paint.
- Auth-gated fragments on an otherwise public, CDN-cached page.
Two things to remember. First, server:defer renders on the server, so it needs an adapter installed (Cloudflare, Node, Vercel…) — the same requirement as any on-demand rendering; without one you’ll hit the “an adapter is required” error. Second, it’s not for client interactivity — if the piece needs to respond to clicks, that’s a client island (a client directive), possibly in addition. Server islands are about deferring server-rendered output, not hydrating JavaScript.