komal.nakrani
Browse Themes
ThemesCategoriesDocsBlogTips & Tricks
Components & Islands••By Komal Nakrani

Which Client Directive Should I Use in Astro?

Which client directive for an Astro island? None, client:visible, client:idle, client:load, client:media or client:only: a quick decision flow with examples.

#Astro#Decision Guide#Client Directives#Islands

Which client directive to use depends on two things: whether the component needs to be interactive at all, and when the user might interact with it. If it doesn’t need state or event handlers, use no directive. If it’s below the fold, use client:visible. If it’s visible on load but not urgent, use client:idle. Use client:load only for controls people touch straight away, client:media for UI that exists at one screen size, and client:only only when the component can’t render on the server.

Key Takeaways

  • No directive is the best directive: the component renders to HTML and ships no JavaScript.
  • client:visible is the right default for most interactive components.
  • client:load competes with your main content for bandwidth and CPU; reserve it.
  • Small interactions are often better as a plain <script> in an Astro component.

Decision flow

  1. Does it need state, effects or event handlers? No → no directive (or rewrite it as an .astro component).
  2. Is it a small interaction, like a toggle, tabs or a copy button? Yes → consider an Astro component with a <script> instead of a framework island.
  3. Does it only matter at certain screen sizes? Yes → client:media="(query)".
  4. Does it break when rendered on the server (uses window while rendering)? Yes → try moving that code into an effect first; if you can’t → client:only="framework".
  5. Is it below the fold? Yes → client:visible (add rootMargin for heavy components).
  6. Will users interact with it within the first second or two? Yes → client:load. No → client:idle.

The directives compared

Directive JS loads Server HTML Typical use
none Never Yes Static rendering of a framework component
client:visible On scroll into view Yes Carousels, comments, maps, below-fold forms
client:idle When browser is idle Yes Header search, non-urgent widgets
client:load Immediately Yes Above-the-fold forms, primary controls
client:media When query matches Yes Mobile nav, desktop-only tools
client:only Immediately, browser only No Browser-only libraries

Examples

<!-- Decorative React component, no interactivity -->
<FeatureGrid />

<!-- Newsletter form halfway down a post -->
<Newsletter client:visible />

<!-- Search in the header -->
<SearchBox client:idle />

<!-- Hero sign-up form above the fold -->
<SignupForm client:load />

<!-- Drawer that only exists on mobile -->
<MobileNav client:media="(max-width: 768px)" />

<!-- Map library that touches window on import -->
<Map client:only="react" />

<!-- Heavy chart: start loading before it's on screen -->
<Chart client:visible={{ rootMargin: '400px' }} />

Costs to keep in mind

  • Every hydrated framework ships its runtime once per page. One React island means React on that page.
  • Two frameworks mean two runtimes. Standardise on one for islands.
  • client:only renders nothing until JavaScript runs: reserve space to avoid layout shift, and keep important content out of it.

To measure what each island adds, see finding what’s bloating your Astro bundle. The timing details are in lazy-loading islands, and all directives are listed in the directives cheatsheet. For the broader picture, read the Astro components guide.

FAQ

What’s the default client directive in Astro?

There isn’t one. Without a directive, a framework component ships no JavaScript.

Is client:visible bad for SEO?

No. The server-rendered HTML is in the page. Only the JavaScript waits.

The directives reference has the formal rules.