πŸ”§ Error Fixes
Β· 1 min read

Astro: Component Not Interactive β€” Hydration Directive Missing


Component renders but buttons/events don't work

Your Astro component renders as static HTML. You need a hydration directive to make it interactive.

Why this happens

Astro renders all components as static HTML by default β€” this is called β€œIslands Architecture.” Unlike frameworks like Next.js or Nuxt, Astro ships zero JavaScript unless you explicitly opt in. If you forget to add a client:* directive, the component’s HTML appears on the page but none of its event handlers, state, or interactivity will work.

Fix 1: Add a client directive

---
import Counter from './Counter.jsx';
---

<!-- ❌ Static β€” no interactivity -->
<Counter />

<!-- βœ… Interactive on page load -->
<Counter client:load />

<!-- βœ… Interactive when visible -->
<Counter client:visible />

<!-- βœ… Interactive on idle -->
<Counter client:idle />

Fix 2: Choose the right directive

  • client:load β€” hydrate immediately (above the fold)
  • client:idle β€” hydrate when browser is idle (below the fold)
  • client:visible β€” hydrate when scrolled into view
  • client:media β€” hydrate at a media query breakpoint
  • client:only β€” skip SSR, client-render only

Alternative solutions

If you only need a small amount of interactivity (like a toggle or accordion), consider using vanilla JavaScript in a <script> tag instead of hydrating an entire framework component:

<button id="toggle">Click me</button>
<script>
  document.getElementById('toggle')?.addEventListener('click', () => {
    alert('No framework needed!');
  });
</script>

You can also use client:only="react" if the component relies on browser-only APIs and doesn’t need SSR at all.

Prevention

  • Make it a habit to always add a client:* directive when importing interactive framework components (React, Vue, Svelte, etc.) into .astro files.
  • Use client:visible or client:idle by default to keep your page fast, and only reach for client:load when the component is above the fold and needs to be interactive immediately.

Related: Astro: Content Collection Schema Validation Error Β· Vite vs Webpack