Astro: Unable to render component - Missing client directive
Astroでクライアントコンポーネントのディレクティブが不足している場合のエラー
概要
Astroでインタラクティブなコンポーネント(React、Vue、Svelte等)を使用する際に、クライアントディレクティブを指定していない場合に発生するエラーです。
エラーメッセージ
Unable to render Component because there is no client directive
This component contains interactive elements but is not hydrated on the client
Error: Cannot use hooks in a server component. Add a client directive.
原因
Astroはデフォルトですべてのコンポーネントをサーバーサイドでレンダリングし、JavaScriptを送信しません。インタラクティビティが必要な場合は、明示的にクライアントディレクティブを指定する必要があります。
解決策
1. クライアントディレクティブを追加
---
// src/pages/index.astro
import Counter from '../components/Counter.jsx'
---
<!-- NG: クライアントディレクティブなし -->
<Counter />
<!-- OK: 適切なディレクティブを追加 -->
<Counter client:load />
2. ディレクティブの種類
---
import Component from '../components/Component.jsx'
---
<!-- ページ読み込み時に即座にハイドレート -->
<Component client:load />
<!-- ページがアイドル状態になったらハイドレート -->
<Component client:idle />
<!-- コンポーネントが表示されたらハイドレート -->
<Component client:visible />
<!-- 特定のメディアクエリでハイドレート -->
<Component client:media="(max-width: 768px)" />
<!-- ハイドレートしない(静的HTML出力のみ) -->
<Component client:only="react" />
3. 使い分けの指針
---
// ヘッダーのナビゲーション(すぐに必要)
import Header from '../components/Header.jsx'
// コメントセクション(後でよい)
import Comments from '../components/Comments.jsx'
// フッターのニュースレター(見えたとき)
import Newsletter from '../components/Newsletter.jsx'
---
<Header client:load />
<main>
<article>...</article>
<Comments client:idle />
</main>
<Newsletter client:visible />
4. フレームワーク固有の設定
| |
5. 状態の共有
---
// Nano Storesを使った状態共有
import { Counter } from '../components/Counter.jsx'
import { Display } from '../components/Display.vue'
---
<!-- 異なるフレームワーク間で状態を共有 -->
<Counter client:load />
<Display client:load />
| |
6. client:onlyの使用
---
// SSRをスキップしてクライアントのみでレンダリング
import BrowserOnlyChart from '../components/Chart.jsx'
---
<!-- ブラウザAPIが必要なコンポーネント -->
<BrowserOnlyChart client:only="react" />
7. スロットとの組み合わせ
---
import Wrapper from '../components/Wrapper.jsx'
---
<Wrapper client:load>
<p>This content is passed as a slot</p>
</Wrapper>
デバッグ
---
// 開発時にハイドレーション状態を確認
import Component from '../components/Component.jsx'
---
<Component client:load />
<script>
// ハイドレーション完了を確認
document.addEventListener('astro:page-load', () => {
console.log('Page fully hydrated')
})
</script>
関連エラー
関連エラー
Astro の他のエラー
この記事は役に立ちましたか?