コンテンツにスキップ

フロントエンドフレームワーク

お気に入りのコンポーネントフレームワークを手放すことなく、Astroウェブサイトを構築できます。好きなUIフレームワークを使ってAstroアイランドを作成しましょう。

フロントエンドフレームワークの公式インテグレーション

Astroは、ReactPreactSvelteVueSolidJSAlpineJSなど、人気のフレームワークを公式インテグレーションとしてサポートしています。

インテグレーションディレクトリでは、さらに多くのコミュニティがメンテナンスするフレームワークインテグレーション(Angular、Qwik、Elmなど)を見つけられます。

UIフレームワーク

インテグレーションのインストール

プロジェクトに、これらのAstroインテグレーションを1つまたは複数インストールして設定できます。

Astroインテグレーションのインストールと設定の詳細については、インテグレーションガイド (EN)を参照してください。

:::tipお好みのフレームワークの使用例を見たいですか?astro.newにアクセスして、フレームワークテンプレートを選んでみてください。:::

フレームワークコンポーネントの使用

JavaScriptフレームワークのコンポーネントを、Astroコンポーネントと同じように、Astroのページ、レイアウト、コンポーネントで使用できます。すべてのコンポーネントを/src/componentsにまとめることも、好きなように整理することも可能です。

フレームワークコンポーネントを使用するには、Astroコンポーネントスクリプトで相対パスからインポートします。そして、コンポーネントテンプレート内で他のコンポーネント、HTML要素、JSXライクな式とともに使用します。

---
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<html>
  <body>
    <h1>AstroではReactコンポーネントを直接使用できます!</h1>
    <MyReactComponent />
  </body>
</html>

デフォルトでは、フレームワークコンポーネントは静的なHTMLとしてサーバー上でのみレンダリングされます。これはインタラクティブではないテンプレート用のコンポーネントに便利であり、クライアントに不要なJavaScriptが送信されることを防ぎます。

インタラクティブなコンポーネントのハイドレーション

フレームワークコンポーネントは、client:*ディレクティブを使用してインタラクティブ(ハイドレートされた状態)にできます。これらはコンポーネントの属性であり、コンポーネントのJavaScriptをいつブラウザに送信するかを決定します。

client:onlyを除くすべてのclientディレクティブでは、コンポーネントはまずサーバー上で静的なHTMLとしてレンダリングされます。コンポーネントのJavaScriptは、選択したディレクティブに応じてブラウザに送信されます。その後、コンポーネントがハイドレートされてインタラクティブになります。

---
// 例: フレームワークコンポーネントをブラウザでハイドレート
import InteractiveButton from '../components/InteractiveButton.jsx';
import InteractiveCounter from '../components/InteractiveCounter.jsx';
import InteractiveModal from '../components/InteractiveModal.svelte';
---
<!-- このコンポーネントのJSはページ読み込み時にインポートが開始されます -->
<InteractiveButton client:load />

<!-- このコンポーネントのJSは、ユーザーがスクロールして
コンポーネントがページ上に表示されるまでクライアントに送信されません -->
<InteractiveCounter client:visible />

<!-- このコンポーネントはサーバーではレンダリングされず、ページ読み込み時にクライアントでレンダリングされます -->
<InteractiveModal client:only="svelte" />

コンポーネントのレンダリングに必要なJavaScriptフレームワーク(React、Svelteなど)は、コンポーネント自体のJavaScriptとともにブラウザに送信されます。ページ上の複数のコンポーネントが同じフレームワークを使用している場合、フレームワークは一度だけ送信されます。

:::note[アクセシビリティ]フレームワーク固有のアクセシビリティパターンのほとんどは、Astroでこれらのコンポーネントを使用する場合も同様に機能します。アクセシビリティ関連のJavaScriptが適切なタイミングで正しく読み込まれ実行されるよう、適切なclientディレクティブを選択してください!:::

利用可能なハイドレーションディレクティブ

UIフレームワークコンポーネントで利用できるハイドレーションディレクティブには、client:loadclient:idleclient:visibleclient:media={QUERY}client:only={FRAMEWORK}があります。

これらのハイドレーションディレクティブの詳しい説明と使い方については、ディレクティブリファレンスを参照してください。

フレームワークを混在させる

同じAstroコンポーネント内で、複数のフレームワークのコンポーネントをインポートしてレンダリングできます。

---
// 例: 同じページで複数のフレームワークコンポーネントを混在させる
import MyReactComponent from '../components/MyReactComponent.jsx';
import MySvelteComponent from '../components/MySvelteComponent.svelte';
import MyVueComponent from '../components/MyVueComponent.vue';
---
<div>
  <MySvelteComponent />
  <MyReactComponent />
  <MyVueComponent />
</div>

Astroはファイル拡張子に基づいてコンポーネントを認識しレンダリングします。同じファイル拡張子を使用するフレームワーク(ReactとPreactなど)を区別するには、複数のJSXフレームワークをレンダリングするための追加設定が必要です。

:::caution複数のフレームワークのコンポーネントを含むことができるのはAstroコンポーネント(.astro)のみです。:::

フレームワークコンポーネントへのpropsの受け渡し

Astroコンポーネントからフレームワークコンポーネントにpropsを渡せます。

---
import TodoList from '../components/TodoList.jsx';
import Counter from '../components/Counter.svelte';
---
<div>
  <TodoList initialTodos={["Astroを学ぶ", "PRをレビューする"]} />
  <Counter startingCount={1} />
</div>

client:*ディレクティブを使用してインタラクティブなフレームワークコンポーネントに渡すpropsは、シリアライズ可能である必要があります。つまり、ネットワーク経由の転送や保存に適した形式に変換できなければなりません。ただし、Astroはすべてのデータ構造をシリアライズできるわけではないため、ハイドレートされるコンポーネントにpropsとして渡せるものには制限があります。

サポートされているprop型は、プレーンなオブジェクト、numberstringArrayMapSetRegExpDateBigIntURLUint8ArrayUint16ArrayUint32ArrayInfinityです。

関数などのサポートされていないデータ構造をコンポーネントに渡した場合、サーバーレンダリング時にのみ使用でき、インタラクティブな機能のためには使用できません。たとえば、ハイドレートされるコンポーネントに関数を渡すことはサポートされていません。Astroはサーバーからクライアントで実行可能な形式で関数を渡すことができないためです。

フレームワークコンポーネントへの子要素の受け渡し

Astroコンポーネント内から、フレームワークコンポーネントに子要素を渡すことができます。各フレームワークには子要素を参照するための独自のパターンがあります。React、Preact、Solidはchildrenという特別なpropを使用し、SvelteとVueは<slot />要素を使用します。

---
import MyReactSidebar from '../components/MyReactSidebar.jsx';
---
<MyReactSidebar>
  <p>テキストとボタンを含むサイドバー。</p>
</MyReactSidebar>

さらに、名前付きスロットを使用して、特定の子要素をグループ化できます。

React、Preact、Solidでは、各スロットはトップレベルのpropに変換されます。kebab-caseのスロット名はcamelCaseに変換されます。

---
import MySidebar from '../components/MySidebar.jsx';
---
<MySidebar>
  <h2 slot="title">Menu</h2>
  <p>テキストとボタンを含むサイドバーです。</p>
  <ul slot="social-links">
    <li><a href="https://twitter.com/astrodotbuild">Twitter</a></li>
    <li><a href="https://github.com/withastro">GitHub</a></li>
  </ul>
</MySidebar>
// src/components/MySidebar.jsx
export default function MySidebar(props) {
  return (
    <aside>
      <header>{props.title}</header>
      <main>{props.children}</main>
      <footer>{props.socialLinks}</footer>
    </aside>
  )
}

SvelteとVueでは、name属性をもつ<slot>要素を使用してこれらのスロットを参照できます。kebab-caseのスロット名はそのまま保持されます。

// src/components/MySidebar.svelte
<aside>
  <header><slot name="title" /></header>
  <main><slot /></main>
  <footer><slot name="social-links" /></footer>
</aside>

フレームワークコンポーネントのネスト

Astroファイル内では、フレームワークコンポーネントの子要素もハイドレートされるコンポーネントにできます。つまり、これらのフレームワークのコンポーネントを再帰的にネストできます。

---
import MyReactSidebar from '../components/MyReactSidebar.jsx';
import MyReactButton from '../components/MyReactButton.jsx';
import MySvelteButton from '../components/MySvelteButton.svelte';
---
<MyReactSidebar>
  <p>テキストとボタンを含むサイドバーです。</p>
  <div slot="actions">
    <MyReactButton client:idle />
    <MySvelteButton client:idle />
  </div>
</MyReactSidebar>

:::cautionフレームワークコンポーネントファイル自体(.jsx.svelteなど)では、複数のフレームワークを混在させることはできません。:::

これにより、好みのJavaScriptフレームワークで「アプリ」全体を構築し、親コンポーネントを通じてAstroページにレンダリングできます。

:::noteAstroコンポーネントは、ハイドレートされるフレームワークコンポーネントを含む場合でも、常に静的なHTMLにレンダリングされます。そのため、渡せるのはHTMLのレンダリングに関与しないpropsのみです。AstroコンポーネントからフレームワークコンポーネントにReactの「render props」を渡すことはできません。このパターンが必要とするクライアントランタイムの動作をAstroコンポーネントは提供できないためです。代わりに名前付きスロットを使用してください。:::

フレームワークコンポーネント内でAstroコンポーネントを使用できますか?

UIフレームワークコンポーネントは、そのフレームワークの「アイランド」になります。これらのコンポーネントは、そのフレームワーク自身のインポートとパッケージのみを使用し、そのフレームワークのコードとして完全に有効なかたちで記述する必要があります。UIフレームワークコンポーネント(.jsx.svelteなど)内で.astroコンポーネントをインポートすることはできません。

ただし、Astroの<slot />パターンを使用して、Astroコンポーネントが生成した静的コンテンツを、.astroコンポーネント内でフレームワークコンポーネントの子要素として渡すことは可能です。

---
import MyReactComponent from  '../components/MyReactComponent.jsx';
import MyAstroComponent from '../components/MyAstroComponent.astro';
---
<MyReactComponent>
  <MyAstroComponent slot="name" />
</MyReactComponent>

Astroコンポーネントをハイドレートできますか?

Astroコンポーネントにclient:修飾子を使ってハイドレートしようとすると、エラーが発生します。

Astroコンポーネントは、クライアントサイドのランタイムをもたないHTMLのみのテンプレートコンポーネントです。ただし、Astroコンポーネントテンプレート内で<script>タグを使用して、グローバルスコープで実行されるJavaScriptをブラウザに送信することは可能です。

貢献する コミュニティ スポンサー