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

Fix: Missing Hint on client:only Directive in Astro

Astro's 'Missing hint on client:only directive' needs a framework name: client:only="react", "vue", "svelte", "solid-js" or "preact".

#Astro#Errors#Client Directives#Islands

Astro shows “Missing hint on client:only directive” when you write client:only without a value. Unlike other directives, client:only skips server rendering, so Astro never runs the component on the server to discover which framework it belongs to. You have to name it: client:only="react", "preact", "vue", "svelte" or "solid-js". The error message suggests the likely value.

Key Takeaways

  • client:only always needs a framework name as its value.
  • The value is the renderer name: react, preact, vue, svelte or solid-js.
  • Prefer client:load or client:visible unless the component truly can’t render on the server.
  • Components with client:only produce no HTML until JavaScript runs, so give them space or a fallback.

The fix

---
import Map from '../components/Map.tsx';
---
<!-- Wrong -->
<Map client:only />

<!-- Right -->
<Map client:only="react" />

Valid values match the official integrations:

Framework Value
React client:only="react"
Preact client:only="preact"
Vue client:only="vue"
Svelte client:only="svelte"
Solid client:only="solid-js"

Should you use client:only at all?

client:only exists for components that break during server rendering, typically because they touch window, document or localStorage while rendering, or wrap a browser-only library such as a map or charting tool.

It has costs:

  • No HTML in the initial page. Search engines and users without JavaScript see nothing in its place.
  • Layout shift. The component appears after the script runs, pushing content down unless you reserve space.
  • Slower perceived load. The user waits for the download before seeing anything.

Often you can keep server rendering and move the browser-only code into an effect:

// src/components/Map.tsx
import { useEffect, useRef } from 'react';

export default function Map() {
  const ref = useRef<HTMLDivElement>(null);
  useEffect(() => {
    // browser-only library loads here, after hydration
    import('some-map-library').then(({ createMap }) => createMap(ref.current!));
  }, []);
  return <div ref={ref} style={{ aspectRatio: '16 / 9' }} />;
}

Then <Map client:visible /> renders a sized placeholder on the server and loads the map when it scrolls into view. Lazy-loading islands covers client:visible timing.

Showing something before it loads

Pass a fallback through the fallback slot, which Astro renders in place until the component mounts:

<Map client:only="react">
  <div slot="fallback" class="map-placeholder">Loading map…</div>
</Map>

If the integration isn’t installed at all, you’ll see No matching renderer found instead. Every directive is compared in the Astro components guide, and the directives reference has the full rules.

FAQ

Why does client:only need a value when client:load doesn’t?

Other directives render the component on the server first, which tells Astro which renderer to use. client:only skips that step, so Astro needs the hint.

Is client:only bad for SEO?

Its content isn’t in the server HTML, so crawlers that don’t run JavaScript won’t see it. Keep important content out of client:only components.