komal.nakrani
Browse Themes
ThemesCategoriesDocsBlogTips & Tricks
Server Rendering••By Komal Nakrani

Fix: Cannot Use Server Islands Without an Adapter

Astro's 'Cannot use server islands without an adapter' appears when a component uses server:defer on a site with no adapter. Add an adapter or render it statically.

#Astro#Errors#Server Islands#Adapters

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:defer needs an adapter even if every page is static.
  • The page itself can stay prerendered and cached; only the island runs per request.
  • Remove server:defer if 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.