[Next.js] Headタグ内のタグ重複を防ぐ
結論
重複を避けたいタグに key
オプションを追加し、同名のキーを設定します。
import Head from 'next/head'
function IndexPage() {
return (
<div>
<Head>
<title>My page title</title>
<meta property="og:title" content="My page title" key="title" />
</Head>
<Head>
<meta property="og:title" content="My new title" key="title" />
</Head>
<p>Hello world!</p>
</div>
)
}
export default IndexPage
こちらのコードの場合、重複しているmetaタグのうち後者のみがレンダリングされます。
next/head Dedupe only items with unique key #5800
背景
当ブログは、ブログに関する情報は pages/_app.tsx
のHeadタグ内に、ブログ記事ごとの情報は lib/components/layout.tsx
のHeadタグ内にメタ情報として設定してあります。
しかし、上記で示したようなmetaタグの key
オプションが設定されていなかったため、og:title
等のOGPに関するmetaタグが重複したままparseされてしまい、例えばSlackチャンネルにブログ記事のリンクを貼り付けた際に、各記事のタイトル等のメタ情報が表示されませんでした。
その他の方法
こちらのreact-helmetというライブラリを使っても解決できそうです。
Headタグ内のmetaタグが重複した場合、ネストしている子コンポーネントのタグをparseします。
使い方も簡単で、
import React from "react";
import {Helmet} from "react-helmet";
class Application extends React.Component {
render () {
return (
<div className="application">
<Helmet>
<meta charSet="utf-8" />
<title>My Title</title>
<link rel="canonical" href="http://mysite.com/example" />
</Helmet>
...
</div>
);
}
};
このように対象のタグを <Helmet>
で囲むだけで対応してくれます。
ただ、Nextプロジェクトで試してみたところ、
Unhandled Runtime Error
TypeError: Cannot read property 'tagName' of null
エラーが発生してしまいビルドできなかったです。
Next.jsの場合はこちらのサンプルリポジトリを参考にすると実現できそうです💪
とはいえ、Next.jsの場合は最初のやり方で対処してくれるので、 react-helmet
を使う必要はなさそうです。
さいごに
今回の件でドキュメントの重要性を再確認できました。Next.jsの場合ドキュメントは英語ではありますが、フレームワーク自体がシンプルなのでドキュメントも読みやすいです。なので、毛嫌いせずに読み込んでみます。
OpenGraphに関しては、以下のサイトでURLを入力することでプロパティ設定を調べることができます。
Facebook for Developers / シェアデバッガー
修正が必要な箇所や、SNSにURLを投稿した際のプレビューなども確認することができます。