コンテンツにスキップ

初めてのレイアウトを作成する

ここで学ぶことは…

  • 共通要素をページレイアウトにリファクタリングする
  • Astroの<slot />要素を使用して、ページの内容をレイアウト内に配置する
  • ページ固有の値をレイアウトにpropsとして渡す

まだいくつかのAstroコンポーネントが各ページで繰り返しレンダリングされています。さらにリファクタリングを進めて、共通のページレイアウトを作成しましょう!

初めてのレイアウトコンポーネントを作成する

セクションタイトル: 初めてのレイアウトコンポーネントを作成する
  1. src/layouts/BaseLayout.astroに新しいファイルを作成します。(まず新しいlayoutsフォルダを作成する必要があります。)

  2. index.astroすべてのコンテンツを新しいファイルBaseLayout.astroにコピーします。

    src/layouts/BaseLayout.astro
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "ホームページ";
    ---
    <html lang="ja">
    <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>{pageTitle}</title>
    </head>
    <body>
    <Header />
    <h1>{pageTitle}</h1>
    <Footer />
    <script>
    import "../scripts/menu.js";
    </script>
    </body>
    </html>
  1. src/pages/index.astroのコードを以下に置き換えます。

    src/pages/index.astro
    ---
    import BaseLayout from '../layouts/BaseLayout.astro';
    const pageTitle = "Home Page";
    ---
    <BaseLayout>
    <h2>私の素晴らしいブログのサブタイトル</h2>
    </BaseLayout>
  2. ブラウザのプレビューを再度開いて、何が変わったか(あるいは、ネタバレになりますが、何が変わっていないか)を確認します。

  3. src/layouts/BaseLayout.astroのフッターコンポーネントの直前に<slot />要素を追加し、ブラウザのプレビューでホームページを開いて、今度はどこが変わったのかを確認します!

    src/layouts/BaseLayout.astro
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "ホームページ";
    ---
    <html lang="ja">
    <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>{pageTitle}</title>
    </head>
    <body>
    <Header />
    <h1>{pageTitle}</h1>
    <slot />
    <Footer />
    <script>
    import "../scripts/menu.js";
    </script>
    </body>
    </html>

<slot />を使うと、<Component></Component>の開始タグと終了タグの間に書かれた子コンテンツを、Component.astroファイルに挿入(または「スロットイン、slot in」)できるのです。

  1. index.astroで、コンポーネント属性を使ってレイアウトコンポーネントにページタイトルを渡します。

    src/pages/index.astro
    ---
    import BaseLayout from '../layouts/BaseLayout.astro';
    const pageTitle = "ホームページ";
    ---
    <BaseLayout pageTitle={pageTitle}>
    <h2>私の素晴らしいブログのサブタイトル</h2>
    </BaseLayout>
  2. BaseLayout.astroレイアウトコンポーネントのスクリプトを、ページタイトルを定数として定義するのではなく、Astro.propsを介して受け取るように変更します。

    src/layouts/BaseLayout.astro
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "ホームページ";
    const { pageTitle } = Astro.props;
    ---
  3. ブラウザのプレビューを開き、ページタイトルが変わっていないことを確認します。値は同じですが、実際は動的にレンダリングされています。また、各ページは自身のタイトルをレイアウトに対して指定できるようになりました。

やってみよう - レイアウトをすべてのページで使用する

セクションタイトル: やってみよう - レイアウトをすべてのページで使用する

他のblog.astroabout.astroページをリファクタリングし、<BaseLayout>コンポーネントを使って共通のページ要素をレンダリングするようにしましょう。

以下を忘れないでください。

  • コンポーネント属性を介してページタイトルをpropsとして渡します。

  • 共通要素のHTMLレンダリングをレイアウトに任せます。

  • 各ページから、レイアウトのおかげでそのページがレンダリングする必要がなくなったものを削除します。

    • HTML要素
    • コンポーネントとそのインポート文
    • <style>タグ内のCSSルール、たとえば概要ページの<h1>など
    • <script>タグ
  1. Astroコンポーネント(.astroファイル)の機能は以下のうちどれですか?

  2. ページタイトルをページに表示するにはどうすればいいですか?

  3. あるコンポーネントから別のコンポーネントに情報を渡すにはどうすればいいですか?