withastro/astro
Server islands
A server island is a slice of a static page that's rendered on-demand by the server, then injected into the otherwise-cached HTML on the client. Astro lets you mark any component with server:defer and it becomes one.
Purpose
Get the cacheability of a static page and the freshness of a server-rendered component, without paying for a full SSR-on-every-request page.
Key files
| File | Purpose |
|---|---|
packages/astro/src/core/server-islands/vite-plugin-server-islands.ts |
Vite plugin: detects server:defer, generates the placeholder + endpoint. |
packages/astro/src/core/server-islands/endpoint.ts |
The runtime endpoint each server island compiles to. |
packages/astro/src/core/server-islands/shared-state.ts |
Shared state between the placeholder injection and the endpoint. |
packages/astro/src/components/ServerIsland.astro (built-in) |
The placeholder component the plugin generates around. |
How it works
sequenceDiagram
participant Build
participant Page as Static page
participant Browser
participant Endpoint as /_server-islands/<id>
Build->>Page: Render placeholder for <Comp server:defer />
Build->>Endpoint: Emit endpoint that renders <Comp> on demand
Browser->>Page: Request page (cached HTML)
Page-->>Browser: HTML with placeholder + small fetch script
Browser->>Endpoint: GET /_server-islands/<id>?...props
Endpoint-->>Browser: HTML fragment
Browser->>Browser: Replace placeholderThe endpoint is a normal SSR route under _server-islands/. Its props (and any complex objects) are encrypted with the project's runtime key (generated by astro create-key) so the server can verify them and prevent prop tampering. Encryption code: packages/astro/src/core/encryption.ts.
When to use
- Per-user widgets (greeting, cart count) inside an otherwise CDN-cacheable page.
- Frequently-updated data (pricing, weather) on a marketing page.
- A/B test slots that the rest of the page should not invalidate.
Caveats
- Each island is one HTTP request. Bundling many on a high-traffic page can negate the cache wins.
- Islands can only render server-side components — they cannot themselves contain
client:*directives in their root, though their output may. - The encrypted prop payload is opaque to the browser but visible in the DOM. Don't put secrets in it.
Related pages
- systems / build pipeline — where islands are emitted.
- systems / render context — what serves each island fetch.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.