use client のページで metadata を export できない
実際に出るエラー
use client のファイルから metadata や generateMetadata を export すると出るビルドエラーです。
何が起きているか
ボタンを置くために、ページの先頭に 'use client' を書いた。そのページに title も付けたくて metadata を export した。この組み合わせでビルドが止まります。
'use client'
export const metadata = { title: '記事' } // ← ここで止まる
export default function Page() {
// useState や onClick を使っている
}
generateMetadata でも同じです。実機では、文言の "metadata" が "generateMetadata" に変わっただけでした。
なぜ使えないのか
title や description は、HTML の head に入れて最初に返すものです。ページを描き始める前に、サーバーで決まっている必要があります。
'use client' のファイルはブラウザにも送られる部品です。そこから export したものを、描く前の head の材料には使えません。文言が言っているのはこのことです。
直し方:押せる部品だけを切り出す
文言のとおり、ページは Server Component のまま残し、ブラウザで動く部分を別のファイルに移します。
ページ全体を Client にする
'use client' export const metadata = { title: '記事' } export default function Page() { const [n, setN] = useState(0) ... }
metadata を置けない。ページ全体がブラウザへ送られる。
押せる部品だけを Client にする
// app/page.tsx(use client は書かない) import { LikeButton } from './like-button' export const metadata = { title: '記事' } export default function Page() { return <main>...<LikeButton /></main> }
metadata はページに。ブラウザで動くのはボタンだけ。
// app/like-button.tsx
'use client'
import { useState } from 'react'
export function LikeButton() {
const [n, setN] = useState(0)
return <button onClick={() => setN(n + 1)}>{`like=${n}`}</button>
}
実機で確かめました。ビルドが通り、HTML の title に指定した文字が入り、ボタンも描かれていました。
直したあとに確かめること
- ページのファイルの先頭に
'use client'が残っていないか - ブラウザで開き、タブの表示に指定した title が出ているか
- ページの動く部分(ボタンなど)が、切り出したあとも動くか
URL の中身で title を変えたいときは generateMetadata を使います(metadata の解説)。
出典
- nextjs.org/docs/app/api-reference/functions/generate-metadata
- nextjs.org/docs/app/getting-started/server-and-client-components
このページの内容は上記の一次情報を基準に書いています。個人ブログや二次情報を根拠にしていません。