パンくずリストはサイト訪問者が現在地を知るため(サイト内で迷子にならないため)にあるものですが、SEO対策においても重要な施作の一つです。

当サイトでもページの左上に設置しています。

パンくずリストを含めたSEOに関する詳細内容は、以下のページでご確認ください。

SEO対策とは?上位表示を目指すうえで気を付けるべき5つのチェックリスト

WordPressであれば、All in One SEOなどのプラグインを利用すれば簡単に導入できますが、そうでない場合はコードを書く必要があります。

1ページずつ同じコードをコピペして書くこともできますが、記述ミスや手間、保守面を考えると、非常に効率が悪いですよね。

というわけで今回は、プログラムで作成する方法をご紹介します。

実装は、当社で普段から使用しているフレームワークAstroで行います。

アストロについての詳細は以下の記事をご覧ください。

超高速Webサイト構築用フレームワーク”Astro(アストロ)”について

JSX記法(JavaScriptの中にHTMLが記述できる記法)のTypeScriptで記述するため、ReactやNext.jsでも利用できます。

ぜひ参考にしてみてください。

やりたいこと

最終的なブラウザの表示はこうなります。

これをHTMLに出力するとこうなります。

<nav>
  <ol>
   <li><a href="/">Home</a></li>
   <li>当社について</li>
  </ol>
</nav>

下層ページではこうなります。

こちらもHTMLで出力させてみます。

<nav>
  <ol>
   <li><a href="/">Home</a></li>
   <li><a href="/about">当社について</a></li>
   <li>会社情報</li>
  </ol>
</nav>

パンくずコンポーネント(子)

まずはパンくずコンポーネントの完成形のコードを載せておきます

src/components/Breadcrumb.astro


---
const { lists } = Astro.props;
interface ListItem {
  path: string;
  name: string;
}
----
<nav>
  <ol>
    <li>
      <a href="/">Home</a>
    </li>
   {
     lists.map((list: ListItem, index: number) => (
    <li>
      {lists.length - 1 !==index ? (
        <a href={`/${list.path}`}>{list.name}</a>
       ) : (
        <span>{list.name}</span>
       )}
    </li>
     ))
   }
 </ol>
</nav>

一応cssも載せておきます。

li {
    display: inline;
  }
  li:not(:first-child)::before {
    content: ">";
    padding: 0 4px;
  }

コンポーネントの一番上では、親からのデータを受け取っています。

その下に型宣言がしてある通り、親から受け取るのはオブジェクトで、キーはpathとnameでどちらもString型です。

パンくずの呼び出し(親)

コンポーネントを呼び出す側(親)のコードは以下の通りです。

src/pages/about.astro

---
import Breadcrumb from "../components/Breadcrumb.astro";
---
<Breadcrumb lists={[{ name: "当社について" }]}/>

下層ページでは以下のようになります。

src/pages/about/company.astro

---
import Breadcrumb from "../../components/Breadcrumb.astro";
---
<Breadcrumb lists={[
{ name: "当社について", path: "about" },
{ name: "会社情報"}
]}/>

親の方ではこのように書いて、子コンポーネントにデータを渡しています。

ループ部分の解説

では、今回のコードの肝であるコンポーネントのループ部分の解説をしていきます。
src/components/Breadcrumb.astro

{
  lists.map((list: ListItem, index: number) => (
  <li>
   {lists.length - 1 !==index ? (
    <a href={`/${list.path}`}>{list.name}</a>
      ) : (
    <span>{list.name}</span>
    )}
  </li>
 ))
}

親から受け取ったオブジェクト(lists)をマップ関数で一つずつ取り出しています。

listには親から受け取ったpathとnameが入っています。

indexは0から始まる番号です。最初のオブジェクトは0番目、次は1番目といったように自動で番号が振られます。

次は、三項演算子を使っています。

条件式 ? trueの場合に表示 : falseの場合に表示

条件式があり、trueの場合は「?」の後が表示され、falseの場合は「:」の後が表示されるといった内容です。

今回の条件式は、

lists.length - 1 !== index

この部分です。

lists.lenghtはオブジェクトの数です。

この三項演算子の部分を言葉にすると、オブジェクトの数マイナス1がindexの値と一致しない場合はリンク付きの文字を表示し、そうでない場合はただの文字だけを表示するといったコードになります。

分かりやすく言うと、渡ってきた最後のオブジェクトにはリンクをつけず、それより前のオブジェクトにはすべてリンクをつけるという意味です。

まとめ

パンくずリストの由来を調べてみると、童話の「ヘンゼルとグレーテル」で兄弟が道に迷わないようにパンくずを道に置いていったところから取られたようですね。

でも、実際にパンくずを道に置いていると、鳥に食べられたり、虫に運ばれたりしてすぐなくなってしまいますよね。

サイトではそうならないように、しっかり設置しておいてください。

今回のコードはサイト内に表示させるパンくずリストだけでなく、リッチリザルトのパンくずリストにも応用できます。

SEO対策を強化したい方はぜひ導入してみてください。