# Astro Hydration について調べてみた


## Astro で client 側のスクリプトを記述する方法

1. Client Directives を使う
   - 目的: コンポーネントの hydration の制御
   - 方法: React, Solid といった UI フレームワークと組み合わせて使う
2. `<script>` を使う
   - 目的: クライアント側で実行する JavaScript の記述
   - 方法: Astro コンポーネント内で、命令的に記述する

## Client Directives

- React, Solid などのコンポーネントの hydration を制御する。
  - ※ Astroコンポーネントに対しては使えない。Astro コンポーネント内で直接読み込まれた UI フレームワークのコンポーネントに対してのみ利用可能。
- Client Directives を指定しない場合、クライアント側で hydration は行われない。

Client Directives は、hydration を行うタイミングによって、以下の 4 種類に分類される。

1. `client:load`: ページの読み込み開始時
2. `client:idle`: ページの読み込み完了時
3. `client:visible`: 対象のコンポーネントが画面上に表示された時
4. `client:media={string}`: 特定の CSS メディアクエリがマッチした時

これらのより詳しい説明を以下に記す。

https://docs.astro.build/ja/reference/directives-reference/#client-directives

### `client:load`

- 優先順位: 高

ページが読み込まれると即座に hydration が行われる。

```jsx
<BuyButton client:load />
```

### `client:idle`

- 優先順位: 中

ページが読み込みが完了し、`requestIdelCallback`イベントが発火した時に hydration が行われる。

```jsx
<ShowHideButton client:idle />
```

### `client:visible`

- 優先順位: 低

ユーザーが hydration 対象のコンポーネントを画面上で初めて見たときに、hydration が行われる。イベントの発火には `IntersectionObserver` が利用される。

```jsx
<HeavyImageCarousel client:visible />
```

### `client:media`

- 優先順位: 低

値として与えられたCSSメディアクエリが、マッチした時に hydration が行われる。サイドバーのトグルなど、特定のスクリーンサイズでのみ表示されるコンポーネントに対して利用する。

```jsx
<SidebarToggle client:media="(max-width: 50em)" />
```

> [!note]
> すでに CSS を使って要素の表示・非表示を管理している場合、単に`client:visible`を利用した方がシンプルになる可能性がある。

### `client:only`

- 優先順位: 高

サーバー側でのレンダリングを無効化し、クライアント側でのみレンダリングを行う。`client:load`のように、ページが読み込まれると即座に読み込みとレンダリングが行われる。

値として、**コンポーネントの UI フレームワークを明示的に与える**必要がある。これは、サーバー側でのレンダリングを無効化しているため、Astro が UI フレームワークを自動的に判別できないためである。

```jsx
<SomeReactComponent client:only="react" />
<SomePreactComponent client:only="preact" />
<SomeSvelteComponent client:only="svelte" />
<SomeVueComponent client:only="vue" />
<SomeSolidComponent client:only="solid-js" />
```