+++

ブログ記事を公開した後、読者がX (旧Twitter) やLINE、FacebookなどのSNSでリンクをシェアしてくれた際に、「目を引くようなきれいなサムネイル画像」と「分かりやすいタイトル・説明文」がリッチなカード形式で表示されてほしいですよね。
この魅力的なシェア表示を実現するための仕組みが OGP (Open Graph Protocol)Twitter Cards です。

これらのメタタグ(<meta>)を正しく設定しておかないと、シェアされても「ただのURL文字列だけ」がタイムラインに流れることになり、せっかくの拡散のチャンスでもほとんどクリックしてもらえません。テーマ開発の段階でしっかりとSEO・OGP自動出力の対策をしておきましょう!


1. 設定ファイル (hugo.toml) の準備

まずは、SEOに必要な「サイトの説明文」や「デフォルト画像」を設定できるようにします。
hugo.toml[params] セクションを追加してください。

# hugo.toml

# 基本設定
baseURL = '...'
title = '...'

# -----------------------------------------------------------------------------
# サイト独自のパラメータ
# -----------------------------------------------------------------------------
[params]
  description = "これは私の技術ブログです。Hugoの勉強過程を記録しています。"
  ogp_image = "images/ogp.png"  # デフォルトのアイキャッチ画像 (記事に画像がない場合に使われる)

Point:
static/images/ogp.png に、サイトの看板となるデフォルト画像を置いておきましょう(推奨サイズ: 1200x630px)。


2. SEO用Partialの作成

metaタグは数が多くてごちゃごちゃするので、専用の部品(Partial)を作ります。
themes/my-tutorial-theme/layouts/partials/seo.html を新規作成します。

コードの内容

<!-- layouts/partials/seo.html -->

<!-- 基本的なメタタグ -->
{{- $description := "" -}}
{{- if .IsHome -}}
  {{- $description = .Site.Params.description -}}
{{- else if .Params.description -}}
  {{- $description = .Params.description -}}
{{- end -}}

{{- if $description -}}
<meta name="description" content="{{ $description }}">
{{- end -}}

<!-- OGP (Facebook, Line, etc) -->
<meta property="og:title" content="{{ .Title }}">
{{- $og_description := $description -}}
{{- if not $og_description -}}
  {{- $og_description = .Summary | plainify | htmlUnescape | truncate 120 -}}
{{- end -}}
<meta property="og:description" content="{{ $og_description }}">
<meta property="og:type" content="{{ if .IsHome }}website{{ else }}article{{ end }}">
<meta property="og:url" content="{{ .Permalink }}">
<meta property="og:site_name" content="{{ .Site.Title }}">

<!-- 画像設定 (優先度: 記事の画像 > デフォルト画像) -->
{{ if .Params.image }}
<meta property="og:image" content="{{ .Params.image | absURL }}">
{{ else }}
<meta property="og:image" content="{{ .Site.Params.ogp_image | default "images/ogp.png" | absURL }}">
{{ end }}

<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ .Title }}">
<meta name="twitter:description" content="{{ $og_description }}">
{{ if .Params.image }}
<meta name="twitter:image" content="{{ .Params.image | absURL }}">
{{ else }}
<meta name="twitter:image" content="{{ .Site.Params.ogp_image | default "images/ogp.png" | absURL }}">
{{ end }}

ポイント解説

  1. 検索エンジン向け (description):

    • 記事に手動で description を設定していない場合は、タグ自体を出力しません
    • googleなどの検索エンジンは、メタディスクリプションがない場合、本文から自動的に最適なスニペットを生成してくれるため、中途半端な要約が出るよりもSEO的に有利です。
  2. SNSシェア向け (og:description):

    • シェア時には何かしらの説明文が必要なため、description がない場合は 記事の冒頭(Summary)を120文字で切り詰めたもの を自動的に設定します。
    • truncate 120 とすることで、長文がそのまま表示されるのを防いでいます。
  3. 画像設定:

    • もし記事ごとの画像 (.Params.image) がなければ、サイト全体の画像 (.Site.Params.ogp_image) を使う、という「フォールバック(保険)」の処理を入れています。

3. baseof.html で読み込み

最後に、この部品を <head> の中で読み込みます。
layouts/baseof.html を開いてください。

<!-- layouts/baseof.html -->
<head>
    <meta charset="UTF-8">
    <title>{{ .Title }} | {{ .Site.Title }}</title>
    
    <!-- ここに追加! -->
    {{ partial "seo.html" . }}

    {{ $style := "css/style.css" }}
    ...
</head>

OGPを最適化してSNSからの流入を最大化しよう

どんなに質の高い記事を書いても、SNSでシェアされた際に「ただのURLの文字だけ」ではタイムラインの流れに埋もれてしまいクリックされません。
検索エンジン向けの description の出し分けや、SNS向けの画像のフォールバック機構(記事固有の画像がなければサイト共通のアイキャッチを利用する)を仕込んだ seo.html をしっかりと設定しておくことで、SNSからの強力な流入(トラフィック)集客効果が見込めます!🚀