WEBTODESIGN

Hugoでtitleとdescriptionをトップページ・記事ページで分ける

Hugoでは簡単に要素のパーツ分けができるので、記事ページやトップページでヘッダー等を使いまわしますよね。その時metaタグも使い回すことになるので、いつもどおりのmetaタグを設置するとトップページと記事ページでは拾える要素が違うのでうまくいかないことも…。

今回は、トップページと記事ページで場合分けしたmetaタグの書き方を共有します。

titleとdescription

検索エンジンで検索した際に表示されるのが「title」と「description」です。試しに、Googleでnoteを検索してみるとこんな感じ…。

「note ――つくる、つながる、とどける。」がtitleタグ。「クリエイターが~を大切にしています。」がdescriptionタグで設定されている部分です。また、ブックマークする際のブックマーク名にもこのtitleが使われます。

サイトのトップページが検索欄に出る場合はtitleタグにはサイト名とサブタイトルを、descriptionにはサイトの概要を表示させ、ブログの記事が検索欄に出る場合はtitleタグにはブログ記事のタイトル、descriptionにはブログの冒頭部分が表示されていることが多いです。

なので、Hugoのブログでもトップページと記事ページでtitleとdescriptionで表示させる内容を分けていきましょう!

titleの場合分け

titleの場合分けには「with」を使ってみましょう。「with」はパラメーターに値が設定されていたときは実行し、なかったときは飛ばすという簡単で便利な関数です!

実際のコード

<title>{{ with .Params.Title }}{{ . }} | {{ end }}{{ .Site.Title }}</title>

トップページでは「サイト名」のみ、記事ページでは「記事のタイトル | サイト名」というtitleになる記述です。

解説

カッコがいっぱいで、ぱっと見では頭がこんがらがってしまいそうです。ひとつひとつ見ていきましょう。まず、タイトルのタグです。

<title>~</title>

この中に、表示したいタイトルを書き込みます。サイト名は以下の記述で取得できます。

{{ .Site.Title }}

これは、config.tomlファイルの「title」から取得されます。

次に、with関数を使った、記事のタイトルがあるときのみタイトルを取得するという記述です。ここが一番重要ですね。

{{ with .Params.Title }}~{{ end }}

with関数は、指定した値が設定されていた場合内容を実行し、値が設定されていない場合はスキップしてくれるというシンプルな関数です。(withの公式ドキュメント

「.Site.Title」はconfig.tomlから取得する「サイトのtitle」でしたが、「.Params.Title」は各記事から取得する「記事のtitle」です。

記事のtitleが設定されていた場合、次の内容を実行するようにします。

{{ . }} |

withは、指定した値が設定されていた時「.」をその内容に置き換えてくれる機能があります。なので関数を表す{{}}で囲って「{{ . }}」としておくと、記事のタイトルに置き換えてくれます。さらに、記事のタイトルとサイトのタイトルの間に区切りが欲しいので記号の「 | 」を入れています。ここはお好みで。

以上を組み合わせるとこうなります!

<title>{{ with .Params.Title }}{{ . }} | {{ end }}{{ .Site.Title }}</title>

こうすれば、記事のタイトルが設定されていた場合「記事のタイトル | サイト名」と出力してくれます。記事ページではない場合、つまりトップページの場合は記事タイトルが設定されていないのでwithの内容はスキップされ「サイト名」のみがtitleに使われることになります。

descriptionの場合分け

descriptionも考え方は同じです。ただ、各記事に毎回descriptionを設定するのは大変なので…。(そのように設定されているテンプレートもあるので、毎回要約を書けるという方はそのほうがSEO的にいいかもしれません。)今回は、記事ページでは冒頭部分を抜粋してdescriptionに挿入するようにしました。

実際のコード

<meta name="description" content="{{ if .Params.Title }}{{ .Summary }} ...{{ else }}{{ .Site.Params.description }}{{ end }}">
//config.toml
hasCJKLanguage = true
summaryLength = 150

[Params]
description = "サイトの概要文"

記事ページの場合は記事の冒頭150字を、トップページの場合は設定した概要を出力してくれる設定です。

解説

ひとつひとつ見ていきましょう。まずは、概要を示すメタタグです。

<meta name="description" content="~">

content=に続く""の中に表示したい概要を入れます。検索した人がそのサイトや記事について瞬時に判断できるような、簡潔で分かりやすい概要文が理想です!

次に、場合分けのif関数です。with関数と似ていますが、「.」で置き換える機能がありません。(今回ifを使ったのは、withだとエラーが出たからです。「.」を設定しなかったから…?)「.」以外withと使い方は同じです。

{{ if .Params.Title }}①{{ else }}②{{ end }}

titleのときとは違い、descriptionでは「else」を追加しています。「else」は「それ以外」という意味です。もしifが設定されていれば①を実行、そうでなければ②が実行されます。

①には記事の冒頭部分、②には自分で考えたサイトの説明を入れたいです。そこで、①の部分は以下のように記述します。

{{ .Summary }} ...

「.Summary」は記事の冒頭(初期設定70語)を出力してくれる便利な変数です。そのうしろに「 …」を付け加えて、文章が途中で途切れていても違和感のないようにしました。

ただし、これはスペースで区切られたでワードを数えているため、単語間にスペースのない日本語では文字カウントがうまくされず大量に引用されてしまいます。なので、config.tomlにそのカウント方法を以下のように追記します。

//config.toml
hasCJKLanguage = true

また、標準の70語では少なく感じたので150字まで拾うように下記を追記しました。

//config.toml
summaryLength = 150

これで、日本語の150文字がdescriptionに正しく挿入されます。※Summaryについての詳細はHugonoの公式ドキュメントの「Content Summaries」をご参照ください。

次に②にはサイトの概要を入れたいです。config.tomlで独自に設定した値(パラメーター)を取得します。まずは、config.tomlに以下を追記します。(既に同様のパラメーターがある場合はそちらを使ってください。)

//config.toml
[Params]
description = "サイトの概要文"

[Params]は、ここから独自のパラメーターだよ~という宣言です。descriptionは別の文字列でも構いません。そして、メタタグ側には以下のように記述します。

{{ .Site.Params.description }}

こうすれば、config.tomlに記述したdescriptionを取得できます。(テンプレートではなくオリジナルでサイトを作っている方は、わざわざconfigに書かなくても直接書き込んでもいいと思います。)

以上を組み合わせるとこうなります!

<meta name="description" content="{{ if .Params.Title }}{{ .Summary }} ...{{ else }}{{ .Site.Params.description }}{{ end }}">

これで、記事ページの場合は記事の冒頭、トップページの場合は設定した概要が出力されるようになりました!

結果の確認

ブラウザの開発者ツール(ブラウザ上で右クリック→要素を検証など)で実際のページで出力されたタグを確認してみます。

トップページ

記事ページ

無事、構想通りにタグの出力内容を分けることができました!自動的に値が出力されるのがなんとなく快感ですね。

Twitterのカードにも応用できると思うので、次はTwitterのカードの場合分けに挑戦したいと思います。