Astro Islands Architecture — Client-Side Interactivity
In this tutorial, you will learn about Astro Islands Architecture. We cover key concepts, practical examples, and best practices to help you master this topic.
Learn Astro's islands architecture: hydrate only interactive components on the client while serving static HTML for the rest of the page.
In this lesson, you'll understand Astro's core innovation—islands architecture—where interactive components float in a sea of static HTML. Only the interactive "islands" ship JavaScript, making pages load fast while keeping rich interactivity where needed.
What You'll Learn
How islands work, when to use them, how they differ from full client-side hydration, and why this pattern improves Core Web Vitals.
Why It Matters
Most frameworks hydrate entire pages with JavaScript, wasting bandwidth on static content. Islands architecture sends JavaScript only for interactive components, reducing bundle size by 80-90% on content-heavy pages.
Real-World Use
Doda Browser's documentation site uses islands for the search bar and code copy buttons while everything else stays static HTML, achieving near-perfect Lighthouse scores.
flowchart LR
subgraph "Page Output"
A[Static HTML Header]
B["Interactive Island (Search)"]
C[Static HTML Content]
D["Interactive Island (Comments)"]
E[Static HTML Footer]
end
B --> F[Client JS Loaded]
D --> G[Client JS Loaded]
style B fill:#ff5a03,color:#fff
style D fill:#ff5a03,color:#fff
How Islands Work
A static Astro page with interactive components:
---
import SearchBar from "../components/SearchBar.tsx";
import CommentSection from "../components/CommentSection.vue";
---
<html>
<body>
<header>
<nav>Static navigation links</nav>
</header>
<main>
<h1>Documentation</h1>
<!-- This becomes an interactive island -->
<SearchBar client:load />
<article>Static content renders as HTML...</article>
<!-- Another island, hydrates when visible -->
<CommentSection client:visible />
</main>
<footer>Static footer content</footer>
</body>
</html>
Output: The <header>, <article>, and <footer> are pure HTML. <SearchBar> loads its JavaScript immediately. <CommentSection> lazy-loads when scrolled into view. The page is usable before JavaScript finishes loading.
Hydration Directives
Astro provides several client:* directives to control when islands hydrate:
| Directive | Hydration Trigger |
|---|---|
client:load |
Immediately when page loads |
client:idle |
When browser is idle |
client:visible |
When element scrolls into viewport |
client:media |
When media query matches |
client:only |
Client-only (no SSR) |
<!-- Loads immediately -->
<SearchBar client:load />
<!-- Loads after page is idle -->
<AnalyticsWidget client:idle />
<!-- Loads when scrolled into view -->
<LazyImage client:visible />
<!-- Loads only on desktop screens -->
<DesktopChart client:media="(min-width: 768px)" />
<!-- Only renders on client, no SSR -->
<ClientOnlyWidget client:only="react" />
Multiple Framework Islands
Astro supports components from different frameworks in the same page:
---
import ReactPlayer from "../components/ReactPlayer.tsx";
import VueChart from "../components/VueChart.vue";
import SvelteButton from "../components/SvelteButton.svelte";
---
<ReactPlayer client:visible />
<VueChart client:idle />
<SvelteButton client:load />
Each framework's runtime is loaded independently only for its islands. The rest of the page uses no framework code at all.
Why Islands Are Faster
Traditional hydration: React loads for the entire page, even static parts. Islands: only interactive parts load framework JS. For a documentation page with a search bar and comment section, this means 95% of the page uses zero JavaScript.
Common Mistakes
- Omitting the
client:*directive: Framework components withoutclient:*render as static HTML with no interactivity. The component appears but doesn't respond to user input. - Using
client:loadfor everything: This defeats the purpose of islands. Useclient:visibleorclient:idlefor below-the-fold components. - Mixing too many frameworks on one page: Each framework adds its runtime. Two frameworks are fine; five may negate the performance benefit.
- Putting interactivity in
.astrocomponents: Astro components are server-only. Move interactive logic to React, Vue, or Svelte components. - Hydrating components that don't need interactivity: If a component only displays data, keep it as a static
.astrocomponent.
Practice Questions
What is an island in Astro? Answer: An interactive component that hydrates independently while the rest of the page remains static HTML.
Which directive loads a component only when it scrolls into view? Answer:
client:visible. It uses the Intersection Observer API to detect visibility.How do islands improve performance? Answer: By sending JavaScript only for interactive components instead of hydrating the entire page.
Can you use React and Vue islands on the same page? Answer: Yes. Each framework loads independently for its components.
Challenge
Build a landing page with three islands: a React header with navigation, a Vue testimonial carousel, and a Svelte contact form. Use different client:* directives for each.
Mini Project
Create a blog post template with a static content area and interactive comment section using client:visible. The comment section should load only when readers scroll past the article.
FAQ
What's Next
Learn about Astro Client Directives in detail, including advanced usage and custom hydration strategies.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro