Next.jsでパンくずリストを構造化マークアップで実装する方法
こんにちは。CURUCURUエンジニアの水谷です。 先日にNext.jsでパンくずリストを実装しました。 今回はそこでの実装方法も踏まえて解説していきます。
パンくずリストとは?
パンくずリストとは、Webサイトの階層構造を示したものです。
TOP > カテゴリー一覧 > トップス > ポロシャツ
上記のような形をしたものです。
パンくずリストを構造化マークアップするとは?
パンくずリストはWebサイトのユーザーだけでなく、検索エンジンもチェックしています。 しかし、普通にUIとして書くだけでは検索エンジンは認識できません。
そこで、検索エンジンでもわかる形式で書く必要があり、その形式に合わせて書くことを構造化マークアップと言います。
構造化マークアップの種類
構造化マークアップにもいくつか種類がありますが、主に下記が使用されています。
- JSON-LD
- microdata
- RDFa
Googleが推奨しているのがJSON-LDであり、CURUCURUでもJSON-LDを採用しました。
ちなみに、microdataやRDFaはHTMLに埋め込む形式ですが、JSON-LDはJavaScript形式で記載できるためUIに依存せずに書くことができるのもメリットです。
Next.jsでパンくずリストを実装する
まず、基本となる形を書いておきます。
<html>
<head>
<title>Award Winners</title>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [{
"@type": "ListItem",
"position": 1,
"name": "Books",
"item": "https://example.com/books"
},{
"@type": "ListItem",
"position": 2,
"name": "Science Fiction",
"item": "https://example.com/books/sciencefiction"
},{
"@type": "ListItem",
"position": 3,
"name": "Award Winners"
}]
}
</script>
</head>
<body>
</body>
</html>
このコードはこちらから見ることができます。
パンくずリストの項目について
@contextや@contextは固定です。
皇族化マークアップ、パンくずリストであることを書いています。
itemListElement
itemListElementに階層構造を作るページを入れていきます。
@typeはListItemで共通です。 @positionは階層のどの位置にいるかを書きます。 @nameはページの名前を書きます。 @itemはページのURLを書きます。
最後の要素に@itemがないですが、ここはあってもなくてもOKです。 ない場合は現在のページのURLが自動で入ります。
Next.jsで実装する
まずは、上記のコードを生成する関数を作ります。
export interface List {
label: string;
path: string;
}
export const Markup = (list: List[]) => {
let jsonLd = '';
jsonLd += `
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [`;
list.forEach((l, i, array) => {
jsonLd += `{
"@type": "ListItem",
"position": ${i+1},
"name": "${l.label}",
"item": "${l.path}"
}`;
if(i !== (array.length - 1)) {
jsonLd += ',';
}
});
jsonLd += `
]
}`;
return jsonLd;
};
細かいところですが、「,」のある、なしも大事です。 例えば、最後の要素に「,」は不要ですが、点があるだけでエラーが出ます。
そして、この関数で生成したJSON-LDをコンポーネントとして実装します。
interface Props {
jsonLd: string;
}
export const BreadCrumbMarkup = (props: Props)=> {
return(
<Head>
{props.jsonLd && (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{__html: props.jsonLd}}
/>
)}
</Head>
);
};
ポイントはHeadコンポーネントでラップするところです。 headタグ内で書いておくのはもちろんですが、もう1つ役割があります。 検索エンジンのクローラーがパンくずリストを検出できるようにSSGで生成しておく必要があります。 それをHeadコンポーネントでラップすることで実現できるので、Headコンポーネントで括っています。
ちなみに、このHeadコンポーネントはコンポーネントを括るとheadタグに入れてくれません。
なので、HeadコンポーネントでBreadCrumbMarkupコンポーネントをラップするのではなく、 BreadCrumbMarkupコンポーネントの中でHeadコンポーネントを使用しています。
まとめ
今回はパンくずリストをNext.jsで実装する方法を紹介しました。 パンくずリストの理解と、Next.jsの理解がまた一歩深まりました。 何度も先輩にプルリク出して見てもらったので、毎月知識が身についている実感があります。自分も忙しいのに良い先輩です。
メンバー募集
CURUCURUでは開発メンバーを募集中です。 CURUCURUの開発に興味があったり、モダンな開発環境で挑戦してみたいという方がいましたら、ぜひこちらも覗いてみてください!