💫
next/headの気を付けたい仕様
ページのheadを実装していて、文法は間違っていないはずなのに一部の要素が出力されていないことに気づき、調べてみたら以下の仕様を見つけました。ESLintにも型チェックにも引っかからず、アプリケーションは普通に起動するので気づかないままなんてこともありえます。
気を付けたい仕様
条件を満たさない要素は取得しない
条件
- Head要素の直下の子要素
-
<React.Fragment>
か配列でラップされている1階層の要素
title
,meta
or any other elements (e.g.script
) need to be contained as direct children of theHead
element, or wrapped into maximum one level of<React.Fragment>
or arrays—otherwise the tags won't be correctly picked up on client-side navigations.
公式サイト引用
ダメな例
複数ページで使う要素を子コンポーネントして切り出す
PageHead.tsx
import Head from 'next/head'
import { VFC } from 'react'
import ChildHead from './ChildHead'
const PageHead: VFC = () => {
return (
<Head>
<title>ページタイトル</title>
<ChildHead />
</Head>
)
}
export default PageHead
ChildHead.tsx
import { VFC } from 'react'
const ChildHead: VFC = () => {
return (
<>
<link rel="icon" href="/favicon.ico" />
<meta property="twitter:card" content="summary_large_image" />
</>
)
}
export default ChildHead
yarn dev
などでアプリケーションを起動してブラウザの検証ツールで確認するとChildHead
コンポーネントの要素(link
, meta
)が出力されていないことがわかります。
良い例
children
を活用してHead要素の直下で展開させる
PageHead.tsx
import { VFC } from 'react'
import ChildHead from './ChildHead'
const PageHead: VFC = () => {
return (
<ChildHead>
<title>ページタイトル</title>
</ChildHead>
)
}
export default PageHead
ChildHead.tsx
import Head from 'next/head'
import { ReactNode, VFC } from 'react'
type Props = { children: ReactNode }
const ChildHead: VFC<Props> = ({ children }) => {
return (
<Head>
<link rel="icon" href="/favicon.ico" />
<meta property="twitter:card" content="summary_large_image" />
{children}
</Head>
)
}
export default ChildHead
この書き方であればtitle
, link
, meta
の3つの要素が出力されます。
最後に
皆さんの開発しているプロダクトでは期待した全てのheadの要素が出力されていますか?
Discussion