Fix: Cannot Use Server Islands Without an Adapter in Astro

Error message:
Cannot use Server Islands without an adapter.
Adapters & SSR 2025-01-25

What Causes This Error?

This error occurs when you use the server:defer directive (Server Islands) without having a server adapter configured. Server Islands require server-side rendering capabilities.

The Problem

---
// astro.config.mjs - No adapter configured
import Component from './Component.astro';
---

<!-- ❌ Server Islands need an adapter -->
<Component server:defer />

The Fix

Install an Adapter

npx astro add vercel
# or
npx astro add netlify
# or
npx astro add node

Configure for Server Islands

// astro.config.mjs
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
  output: 'hybrid', // or 'server'
  adapter: vercel(),
});
---
import UserProfile from '../components/UserProfile.astro';
---

<!-- ✅ Now Server Islands work -->
<UserProfile server:defer />

Common Scenarios

Understanding Server Islands

---
// Server Islands allow parts of static pages to be server-rendered
import StaticContent from './StaticContent.astro';
import DynamicUser from './DynamicUser.astro';
---

<!-- This is static (built at build time) -->
<StaticContent />

<!-- This is rendered on each request -->
<DynamicUser server:defer />

With Loading Placeholder

---
import UserDashboard from '../components/UserDashboard.astro';
---

<UserDashboard server:defer>
  <!-- Shown while loading -->
  <div slot="fallback">
    <p>Loading your dashboard...</p>
  </div>
</UserDashboard>

Hybrid Mode Setup

// astro.config.mjs
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
  output: 'hybrid', // Static by default, SSR where needed
  adapter: vercel(),
});

Multiple Server Islands

---
import Header from './Header.astro';
import UserNav from './UserNav.astro';
import RecentActivity from './RecentActivity.astro';
import Footer from './Footer.astro';
---

<Header /> <!-- Static -->

<UserNav server:defer>
  <nav slot="fallback">Loading...</nav>
</UserNav>

<main>
  <h1>Welcome</h1>

  <RecentActivity server:defer>
    <p slot="fallback">Loading activity...</p>
  </RecentActivity>
</main>

<Footer /> <!-- Static -->

Alternative: Client-Side Fetching

If you don’t want SSR:

---
// Static page
---

<div id="user-profile">Loading...</div>

<script>
  // Fetch user data on client
  fetch('/api/user')
    .then(res => res.json())
    .then(user => {
      document.getElementById('user-profile').innerHTML = `
        <h2>${user.name}</h2>
        <p>${user.email}</p>
      `;
    });
</script>

Alternative: Full SSR Page

---
// Make entire page server-rendered
export const prerender = false;

const user = await getUser(Astro.cookies.get('session'));
---

<UserProfile user={user} />

When to Use Server Islands

✅ Good use cases:
- User-specific content on otherwise static pages
- Personalized recommendations
- Shopping cart in header
- Auth-dependent UI

❌ Consider alternatives:
- Entire page needs request data → Use SSR
- Data isn't sensitive → Use client-side fetch
- Simple static site → Don't need adapters

Quick Checklist

  • Server Islands require an adapter
  • Use output: 'hybrid' or output: 'server'
  • Install adapter: npx astro add <adapter>
  • Use server:defer directive on components
  • Provide slot="fallback" for loading states