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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

src/pages/interactive-components.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と一緒にブラウザに送信されます。ページ上の複数のコンポーネントが同じフレームワークを使用する場合、フレームワークは一度だけ送信されます。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

src/pages/named-slots.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>
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では、これらのスロットは<slot>要素にname属性を付けて参照できます。また、kebab-caseを使用したスロット名は保持されます。

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

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

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

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

src/pages/nested-components.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>

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

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

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

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

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

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

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

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

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

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

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