Islands Basics
Islands Architecture enables partial hydration โ only interactive parts of your page load JavaScript.
The Problem
Traditional SPAs send JavaScript for the entire page:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Header (static) โ JS loaded โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Article (static) โ JS loaded โ
โ โ
โ Comments (interactive)โ JS needed โ
โ โ
โ Footer (static) โ JS loaded โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Result: Large bundle, slow load, wasted resources.
The Solution
Islands hydrate only interactive components:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Header (static) โ No JS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Article (static) โ No JS โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Comments Island โ JS โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ Footer (static) โ No JS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Result: Minimal JavaScript, fast load, great Core Web Vitals.
Creating an Island
1. Server-Rendered HTML
The server renders an island as a custom element with luna:wc-* attributes:
<wc-counter
luna:wc-url="/static/wc-counter.js"
luna:wc-state="0"
luna:wc-trigger="load"
>
<template shadowrootmode="open">
<button>Count: 0</button>
</template>
</wc-counter>
For server-side rendering with MoonBit, see the MoonBit Tutorial.
2. Client Side (TypeScript)
Create the interactive component:
// wc-counter.ts
import { createSignal, hydrateWC } from '@luna_ui/luna';
interface CounterProps {
initial: number;
}
function Counter(props: CounterProps) {
const [count, setCount] = createSignal(props.initial);
return (
<>
<style>{`:host { display: block; }`}</style>
<button onClick={() => setCount(c => c + 1)}>
Count: {count()}
</button>
</>
);
}
// Register for hydration
hydrateWC("wc-counter", Counter);
3. Hydration
Page loads with server-rendered HTML (instant display)
Luna loader scans for
[luna:wc-url]elementsBased on trigger, loads
/static/wc-counter.jsJavaScript takes over, element becomes interactive
Island Attributes
| Attribute | Purpose |
|---|---|
luna:wc-url | URL to load component JavaScript |
luna:wc-state | Serialized props (JSON) |
luna:wc-trigger | When to hydrate |
customElements.define() is not required โ the loader picks up any element with luna:wc-url, regardless of whether the tag is a registered Custom Element.
How Hydration Works
Server HTML Luna Loader Island Component
โ โ โ
โ luna:wc-url found โ โ
โ โโโโโโโโโโโโโโโโโโ>โ โ
โ โ โ
โ โ Check trigger โ
โ โ (load/idle/visible) โ
โ โ โ
โ โ Load JS module โ
โ โโโโโโโโโโโโโโโโโโโโโโ> โ
โ โ โ
โ โ Call hydrate() โ
โ โ<โโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ<โโโโโโโโโโโโโโโโโโโโ Take over DOM โ
โ Interactive! โ โ
Multiple Islands
Each island is independent. A typical page structure:
<div>
<h1>My Page</h1>
<!-- Search island - hydrates immediately -->
<wc-search luna:wc-url="/wc-search.js" luna:wc-trigger="load">...</wc-search>
<!-- Article - pure HTML, no JS -->
<article>
<p>Static content...</p>
</article>
<!-- Comments island - hydrates when visible -->
<wc-comments luna:wc-url="/wc-comments.js" luna:wc-trigger="visible">...</wc-comments>
<!-- Footer - pure HTML -->
<footer>...</footer>
</div>
Benefits
| Metric | Traditional SPA | Islands |
|---|---|---|
| Initial JS | 100KB+ | ~2KB loader |
| TTI | Slow | Fast |
| LCP | Blocked by JS | Immediate |
| Interactivity | All or nothing | Progressive |
When to Use Islands
Use Islands for:
Interactive widgets (forms, search, comments)
Components needing client state
Dynamic content after load
Don't use Islands for:
Static content (articles, headers)
Content that doesn't need interactivity
Server-only rendered pages
Try It
Think about a typical blog page. Which parts would you make into islands?
Answer
Blog Page Structure:
โโโ Header โ Static (no island)
โโโ Navigation โ Static (no island)
โโโ Article โ Static (no island)
โโโ Share Buttons โ Island (click tracking)
โโโ Comments Form โ Island (form submission)
โโโ Comments List โ Island (live updates)
โโโ Related Posts โ Static (no island)
โโโ Footer โ Static (no island)
Only 3 islands needed for full interactivity!
Next
Learn about Hydration Triggers โ