Hugoブログに多言語対応とhreflang・canonicalなどのSEO設定を適用する構成を示す代表画像

目的

Hugoブログに多言語対応とSEO最適化を適用し、検索エンジンへの露出を最大化するとともに、多言語ユーザーに適切な言語バージョンを提供します。


SEO設定

SEO(Search Engine Optimization、検索エンジン最適化)とは、Googleなどの検索エンジンがサイトのコンテンツを正しく理解し、検索結果に表示できるように、サイト構造とメタデータを最適化する作業です。

この文書では、ブログに適用されたSEO設定をまとめます。

1. 絶対URL - Hugo baseURL設定

  • ファイル: hugo/hugo.toml
  • 内容: baseURL = 'https://blog.plzhans.com'
  • sitemap.xml、RSSフィード、Open Graphなどで正しい絶対URLが生成されます
  • Sitemap (sitemap.xml)、RSSフィード (index.xml) はHugoが自動生成します
  • hugo server(開発時)では自動的にlocalhost:1313を使用するため、別途の処理は不要です

2. robots.txtの自動生成

  • ファイル: hugo/hugo.toml
  • 内容: enableRobotsTXT = true
  • Hugoビルド時にrobots.txtが自動生成されます(すべてのクローラーを許可 + Sitemap URLを含む)

3. Schema.org構造化データ(JSON-LD)

  • ファイル: hugo/layouts/_default/single.html
  • 記事ページ(type != "page")にBlogPostingのJSON-LDを挿入します
  • 含まれる項目: headline、datePublished、dateModified、author、description、mainEntityOfPage
  • Google検索結果でリッチスニペット(作成者、日付など)を表示できます

4. og:image(代表画像) / Open Graph

  • ファイル: src/services/NotionExportService.mjs
  • Notion同期時にコンテンツ内の最初の画像を検出し、front matterのimagesフィールドに自動追加します
  • Open Graphメタタグは、Hugo内蔵テンプレート(_internal/opengraph.html)によって出力され、imagesog:imageとして使用します

5. meta description / Twitter Card

  • ファイル: src/services/NotionExportService.mjs
  • Notionの「要約」プロパティをfront matterのdescriptionフィールドとして出力します
  • Hugo内蔵のopengraph/twitter_cardsテンプレートおよびbaseof.htmlのmeta descriptionで使用されます
  • Twitter Cardのメタタグは、Hugo内蔵テンプレート(_internal/twitter_cards.html)によって出力されます
  • その他のメタタグ(author、viewport)もテーマがデフォルトで提供します

6. Canonical URL

  • ファイル: hugo/layouts/_default/baseof.html
  • テーマ(m10c)のbaseof.htmlをオーバーライドして<link rel="canonical">タグを追加します
  • .Permalinkをcanonical URLとして使用します
  • 多言語hreflangタグも一緒に含まれます(翻訳ページが存在する場合、alternate + x-defaultを出力)

7. Google Analytics(GA4)

  • テーマ(m10c)でデフォルト提供されます
  • Google Search Console認証時にGA連携で認証可能です

多言語SEOの主要要素

HTML lang属性

ページの言語を明示することで、検索エンジンとスクリーンリーダーに言語情報を提供します。

1<html lang="ko">

各言語ごとのページURLを検索エンジンに伝えることで、重複コンテンツの問題を防ぎます。

1<link rel="alternate" hreflang="ko" href="https://blog.plzhans.com/ko/post/example/">
2<link rel="alternate" hreflang="en" href="https://blog.plzhans.com/en/post/example/">
3<link rel="alternate" hreflang="ja" href="https://blog.plzhans.com/ja/post/example/">
4<link rel="alternate" hreflang="x-default" href="https://blog.plzhans.com/ko/post/example/">

Canonical URL(多言語)

各言語をプロの翻訳として作成した場合、canonicalを省略することで、すべての言語バージョンを独立したオリジナルとして認めてもらうことができます。

1<link rel="canonical" href="https://blog.plzhans.com/ko/post/example/">

Hugoでの多言語実装

1. テーマの多言語対応の確認

lang属性の確認(themes/{テーマ}/layouts/_default/baseof.html)

1<!doctype html>
2<html lang=" .Site.Language.Lang ">

relLangURL対応の確認

ホームリンクが言語別URLを維持しているかを確認します。対応していない場合はbaseof.htmlをオーバーライドします。

1<body>
2  <header class="app-header">
3    <a href=" .Site.Home.RelPermalink "><img class="app-header-avatar" src="..." alt="..." /></a>

2. hugo.tomlの多言語設定

 1# デフォルトのコンテンツ言語
 2defaultContentLanguage = "ko"
 3# デフォルト言語もサブディレクトリに含める(/ko/)
 4defaultContentLanguageInSubdir = true
 5
 6[languages]
 7  [languages.ko]
 8    weight = 1
 9    languageName = "한국어"
10
11  [languages.en]
12    weight = 2
13    languageName = "English"
14
15  [languages.ja]
16    weight = 3
17    languageName = "日本語"

3. canonicalタグの追加

テーマが対応していない場合はbaseof.htmlをオーバーライドします。

1<link rel="canonical" href=" .Permalink " />

4. hreflangタグの生成

コンテンツファイルにtranslationKeyを設定

1---
2id: "80"
3translationKey: "80"
4slug: "80-redis-dump-vs-aof"
5title: "Redis dump vs aof"
6---

baseof.htmlにhreflangを追加(テーマが対応していない場合はオーバーライド)

1<link rel="alternate" hreflang=" .Language.Lang " href=" .Permalink " />
2<link rel="alternate" hreflang="x-default" href=" .Permalink " />

トラブルシューティング

URLの重複衝突

Hugoで投稿のアドレスを設定する際は、urlではなくslugを使用する必要があります。

原因

  • slugで設定すると、/ko//en/などの言語プレフィックスが自動的に追加されます
  • urlで強制指定すると、Hugoは言語コードを自動的に追加しません
  • urlを使用する場合、/ko/post/example/en/post/exampleのように、各言語ごとにURL自体に言語コードを直接入れる必要があります
  • urlに言語コードなしで同じパスを指定すると、異なる言語の投稿が同じURLを持つことになり、衝突が発生します

解決方法

  • urlの代わりにslugを使用するように切り替えます
  • hugo.tomldefaultContentLanguageInSubdir = trueを設定し、デフォルト言語を含むすべての言語がサブディレクトリ構造を持つようにします

参考

  • slugだけを指定すると言語コードは自動的に追加されますが、slug自体が特定の言語で書かれている場合は、言語ごとに翻訳する必要があります。slugは英語で作成することを推奨します。

translationKeyを追加したのにhreflangが生成されない

原因

  • テーマがhreflangタグの生成に対応していません。

解決方法

  • baseof.htmlにhreflang関連のコードをオーバーライドして追加します

参照

関連記事