Astro shows “Cannot use server islands without an adapter” when a component has the server:defer directive but the project has no adapter configured. A server island is rendered on the server for each request after the page loads, so something has to run that server code. Install an adapter, or remove server:defer and render the component at build time.
Key Takeaways
server:deferneeds an adapter even if every page is static.- The page itself can stay prerendered and cached; only the island runs per request.
- Remove
server:deferif the component’s content is the same for everyone.- The full message: “Cannot use server islands without an adapter. Please install and configure the appropriate server adapter for your final deployment.”
Where the directive is
grep -rn "server:defer" src/
It looks like this:
<UserMenu server:defer>
<a slot="fallback" href="/login/">Sign in</a>
</UserMenu>
Fix 1: add an adapter
npx astro add node # or cloudflare, netlify, vercel
Keep output at its default. The page stays static; Astro builds a small server route that renders UserMenu per request and the browser swaps it in.
Server islands are usually worth it when one component is personal (a cart count, a user avatar) on an otherwise shared page. The Astro SSR guide explains how they fit with caching.
Fix 2: remove the directive
If the component doesn’t depend on cookies, headers or live data, it can render at build time:
- <UserMenu server:defer>
- <a slot="fallback" href="/login/">Sign in</a>
- </UserMenu>
+ <UserMenu />
Fix 3: load the dynamic part in the browser
For small, non-sensitive data on a fully static site, fetch it client-side instead:
<span id="stock">Checking stock…</span>
<script>
const res = await fetch('https://api.example.com/stock/sku-123');
const { stock } = await res.json();
document.getElementById('stock')!.textContent = `${stock} in stock`;
</script>
This works only with a public API and doesn’t help for anything that depends on a logged-in user’s cookies on your own domain.
Props must be serialisable
Once an adapter is added, remember that props passed to a server island are serialised and encrypted into the request. Pass plain values (strings, numbers, plain objects), not functions or class instances. Astro creates the encryption key automatically; astro create-key generates one to set as ASTRO_KEY when you need it to stay stable across deployments.
Related: Cannot use server-side rendering without an adapter is the same problem for whole pages. Components and directives are covered in the Astro components guide, and the server islands docs are the reference.
FAQ
Do server islands make my page server-rendered?
No. The page can be prerendered. Only the deferred component is rendered on the server, in a separate request.
Which adapter works with server islands?
All official adapters: Node, Cloudflare, Netlify and Vercel.