メタデータ
ルートごとのドキュメントタイトル、description、Open Graph タグ。
ページやレイアウトは、静的な metadata オブジェクトをエクスポートするか、ルートパラメータに依存する値のために非同期の generateMetadata() をエクスポートできます:
import type { Metadata } from 'murasaki'
export const metadata: Metadata = {
title: 'Blog',
description: 'Posts about murasaki.',
}import type { GenerateMetadata } from 'murasaki'
export const generateMetadata: GenerateMetadata = async ({ params }) => {
return { title: `Post: ${params.slug}` }
}generateMetadata は { params } を受け取ります — useParams() がクライアント側で読み取るのと同じ動的セグメントのパラメータです — なので、CMS や API ルート、その他の非同期処理からタイトルを取得できます。
Metadata の形
interface Metadata {
title?: string
description?: string
icons?: {
icon?: string
shortcut?: string
apple?: string
}
openGraph?: {
title?: string
description?: string
images?: string[]
}
}icons のうち、実際にドキュメントへレンダリングされるのは icon(<link rel="icon"> として)だけです — shortcut と apple は将来の互換性のために型だけ用意されていて、まだ適用されません。DOM に現れることを当てにしないでください。
レイアウトがデフォルトを設定し、ページがそれを上書きする
レイアウトの metadata(とページのそれ)はルートからリーフへとマージされます — 各祖先レイアウトのフィールドが先に適用され、その上にマッチしたページのものが適用されます — なので、レイアウトはフォールバックの description や openGraph.images を設定でき、その配下のすべてのページは自分で設定しない限りそれを継承します:
export const metadata: Metadata = {
title: 'My App',
openGraph: { images: ['/og-default.png'] },
}export const metadata: Metadata = {
title: 'My Post',
// openGraph.images は引き続きレイアウトの '/og-default.png' に解決されます —
// ページが実際に設定したフィールドだけが、その上にあるものを上書きします。
}このマージはオブジェクト全体ではなくフィールド単位です: icons と openGraph はキーごとにマージされ(ページが openGraph.title を設定しても、レイアウトの openGraph.images は失われません)、title のようなトップレベルのフィールドは単純に上書きされます。
ページの generateMetadata(存在する場合)は await され、この静的なチェーン全体の上に最後にマージされます — なので、レイアウトのものを含め、静的エクスポートが設定したどのフィールドも上書きできます。
適用される仕組み
ナビゲーションのたびに、<AppRouter> はこのチェーン全体を解決し、ドキュメントに適用します:
document.title(タイトルが実際に解決されたときだけ変更されます — 空にされることはありません)<meta name="description">- Open Graph の
<meta property="og:...">タグ(openGraphフィールドが省略された場合はtitle/descriptionにフォールバックします) icons.iconからの<link rel="icon">
Murasaki が以前追加したタグは、新しいタグが適用される前に削除されるため、ルート間を移動しても前のルートの古いタグが蓄積されるのではなく、きれいに置き換えられます。applyMetadata(これを行う関数で、自分で呼び出す必要がある場合のためにエクスポートされています)は DOM 環境の外では no-op です。
これが設定するのはドキュメントのタイトル/meta タグであり、ネイティブウィンドウのタイトルバーではありません — ウィンドウのタイトルは murasaki.config.ts の window.title(詳しくは設定を参照)から取得され、起動時に一度だけ設定されます。