お好みのUIコンポーネントフレームワークを活かしてAstroでウェブサイトを作成してみましょう。

AstroはReactPreactSvelteVueSolidJSAlpineJSLitのようなさまざまな人気のフレームワークをサポートしています。

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

AstroはReact、Preact、Svelte、Vue、SolidJS、AlpineJS、Litのインテグレーションをオプションとして提供しています。1つまたは複数のAstroインテグレーションをプロジェクトにインストールし、設定できます。

⚙️ Astroのインテグレーションをインストールし、設定するにあたっての詳細はインテグレーションガイドをご覧ください。

⚙️ お好きなフレームワークの例を確認したいですか?astro.newにアクセスして、そのフレームワークのテンプレートを選択してみてください。

フレームワークコンポーネントを利用

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

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

astro
---import MyReactComponent from '../components/MyReactComponent.jsx';---<html>  <body>    <h1>Astroの中でReactコンポーネントを直接使ってください!</h1>    <MyReactComponent />  </body></html>

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

インタラクティブなコンポーネント

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

client:onlyを除く全てのclientディレクティブで、コンポーネントはまず最初にサーバー上でレンダリングされて静的なHTMLを生成します。JavaScriptのコンポーネントは指定したディレクティブに従ってブラウザに送信されます。その後コンポーネントはハイドレートしインタラクティブになります。

astro
---// 例: ブラウザでコンポーネントをハイドレーションするimport InteractiveButton from '../components/InteractiveButton.jsx';import InteractiveCounter from '../components/InteractiveCounter.jsx';import InteractiveModal from "../components/InteractiveModal.svelte"---<!-- このコンポーネントのJavaScriptはページ読み込み時にインポートが開始されます --><InteractiveButton client:load /><!-- このコンポーネントのJavaScriptはユーザーがスクロールしてコンポーネントがページ内に表示されるまでクライアントに送信されません --><InteractiveCounter client:visible /><!-- このコンポーネントはサーバーでレンダリングされませんが、ページ読み込み時にクライアント上でレンダリングされます --><InteractiveModal client:only="svelte" />

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

:::note[アクセシビリティ] これらのコンポーネントをAstroで使用した場合、多くのフレームワーク固有のアクセシビリティパターンは同じように動作するはずです。アクセシビリティに関するJavaScriptが適切に読み込まれ、実行されるよう必ずクライアントディレクティブを設定してください。 :::

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

UIフレームワークコンポーネントで利用可能なハイドレーションのディレクティブがいくつかあります。client:loadclient:idleclient:visibleclient:media={QUERY}client:only={FRAMEWORK}です。

📚 これらのハイドレーションのディレクティブやその使い方を詳しく知りたい場合はディレクティブのリファレンスのページをご覧ください。

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

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

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

:::caution Astroコンポーネント(.astro)だけが複数のフレームワークのコンポーネントを含められます。 :::

フレームワークコンポーネントにPropsを渡す

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

astro
---import TodoList from '../components/TodoList.jsx';import Counter from '../components/Counter.svelte';---<div>  <TodoList initialTodos={["learn Astro", "review PRs"]} />  <Counter startingCount={1} /></div>

:::caution[関数をプロパティとして渡す] フレームワークコンポーネントに関数をプロパティとして渡せますが、それはサーバーレンダリングの間だけ機能します。もしこの関数をハイドレードされたコンポーネント(例えば、イベントハンドラーとして)で使用しようとするとエラーが発生します。

これはAstroでは関数をシリアライズ(サーバーからクライアントへの転送)できないためです。 :::

フレームワークコンポーネントに子要素を渡す

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

astro
---import MyReactSidebar from '../components/MyReactSidebar.jsx';---<MyReactSidebar>  <p>これは、テキストとボタンがあるサイドバーです。</p></MyReactSidebar>

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

React、Preact、Solidでは、これらのスロットはトップレベルのプロパティに変換されます。kebab-caseを使用しているスロット名は、camelCaseに変換されます。

astro
---import MySidebar from '../components/MySidebar.jsx';---<MySidebar>  <h2 slot="title">メニュー</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>
jsx
// src/components/MySidebar.jsxexport default function MySidebar(props) {  return (    <aside>      <header>{props.title}</header>      <main>{props.children}</main>      <footer>{props.socialLinks}</footer>    </aside>  )}

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

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

フレームワークコンポーネントをネストさせる

Astroファイルの中には、フレームワークコンポーネントの子要素もハイドレーションされたコンポーネントにできます。これは、フレームワークのどれからでも、コンポーネントを再帰的にネストできることを意味します。

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のページにレンダリングできます。

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

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

UIフレームワークコンポーネントは、そのフレームワークの「アイランド(島)」になります。これらのコンポーネントは、そのフレームワークの有効なコードとして、独自のインポートやパッケージのみを使用して完全に記述しなければなりません。UIフレームワークコンポーネント(例:.jsx.svelte)の中で.astroコンポーネントをインポートすることはできません。

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

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

Astroコンポーネントをハイドレーションすることはできますか?

client:という修飾子を使ってAstroコンポーネントをハイドレーションしようとするとエラーになるはずです。

Astro コンポーネントはクライアントサイドのランタイムを持たないHTMLのみを表示するコンポーネントです。しかし、<script>タグをAstroコンポーネントのテンプレートの中で使い、グローバルスコープで実行するJavaScriptをブラウザに送信することはできます。

📚 Astroコンポーネントのクライアントサイド<script>タグについてもっと学ぶ