レイアウト

ここでは404ページを含む各ページへ共通のヘッダーとフッターを追加します。共通の部品はReactコンポーネント、ページ全体の共通構造はレイアウトとして管理します。どちらもJSX・TSXで記述できます。

Table of Contents

共通コンポーネントを作る

src/components/header.tsx
type Props = { siteName: string }

export default function Header({ siteName }: Props) {
  return (
    <header>
      <a href="/">{siteName}</a>
      <nav aria-label="メイン">
        <a href="/about">私たちについて</a>
      </nav>
    </header>
  )
}

ページやレイアウトからimportし、propsを渡します。静的な部品にはIslandの指定は必要ありません。

共通レイアウトを作る

src/layouts/index.tsxまたはindex.jsxは、デフォルトですべてのページに適用されます。childrenがページ本文です。

src/layouts/index.tsx
import type { Metadata, LayoutProps } from "minista/types"
import Header from "../components/header"

export const metadata: Metadata = {
  title: "My Site",
}

export default function Layout({ title, children }: LayoutProps) {
  return (
    <html lang="ja">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width" />
        <title>{title}</title>
      </head>
      <body>
        <Header siteName="My Site" />
        <main>{children}</main>
        <footer>My Site</footer>
      </body>
    </html>
  )
}

このレイアウトでは本文をmainで囲むため、ページ側はh1やarticleなどを返します。mainを重ねないように、どちらで本文の領域を定義するか決めておきます。

ページのmetadata.titleはレイアウトの既定タイトルより優先されます。urlで現在のページURLも取得できます。

ページへデータを渡すで用意したgetStaticData()のpropsも、レイアウトで受け取れます。独自のデータを使う場合はLayoutPropsへ型を追加し、そのデータを持たないページも表示できるよう省略可能にして扱います。

構成と出力を確認する

ページに加え、ヘッダーと共通レイアウトを次の場所へ置きます。

プロジェクト構成
src/
├── components/
│   └── header.tsx
├── layouts/
│   └── index.tsx
└── pages/
    ├── index.tsx
    ├── about.md
    └── 404.tsx
ビルド結果
dist/
├── index.html
├── about.html
└── 404.html

コンポーネントやレイアウトごとのHTMLファイルは生成されません。各ページのHTMLへ、共通のヘッダー、本文、フッターが組み込まれます。

はじめるのページは本文だけを返す構成です。既存ページがmainを返している場合は、レイアウトと重ならないように変更してください。

HTML全体を書かないレイアウト

レイアウトがルートのhtml要素を返さない場合は、ministaがhtml head bodyを補います。この形式ではHeadで言語やタイトルを設定できます。

src/layouts/index.tsx
import type { LayoutProps } from "minista/types"
import { Head } from "minista/head"

export default function Layout({ title, children }: LayoutProps) {
  return (
    <>
      <Head htmlAttributes={{ lang: "ja" }}>
        <title>{title}</title>
      </Head>
      <main>{children}</main>
    </>
  )
}

要素の追加や属性指定、同じkeyによる上書きはHeadを参照してください。

ページごとに構成を変える

共通レイアウトの中でurlや独自のmetadataを使って分岐するか、ページ側で別のラッパーコンポーネントを使います。ディレクトリにレイアウトを置くだけで、自動的に入れ子のレイアウトが適用される仕組みではありません。

スタイルはCSSのバンドルで追加します。

次はHeadで、ページごとのhead要素やHTMLの属性を設定します。