Nuxt4でCanonical URLをlayoutで設定する

掲載日
更新日

はじめに

Canonical(カノニカル) URLは複数のパス(URL)でアクセスできるページで、どれが主たるURLかを指定するmetaタグです。

これがないと、GoogleなどのクローラーはわざわざURLをすべて見に行ってくれている?等、そこまで重要じゃないけどよろしくはない状態になります。
(Googleのクローラーは賢いので、重複は重複として扱ってくれてるので検索エンジンに同じページが2つも3つも載るということはないみたいですが。)
今回はNuxt4でそのCanonical URLを設定しようとしたら意外とハマったので解決までの備忘録です。

結論

layoutsディレクトリ配下の、Canonical URLを設定したいファイルに以下の処理を追記します。

const route = useRoute()
const url = useRequestURL()
const getCanonicalPath = (path: string) => {
    if (path.endsWith('/')) {
        path = path.slice(0, -1)
    }
    const baseUrl = url.protocol + '//' + url.host
    return baseUrl + path
}
useHead(() => ({
    link: [
        {
            rel: 'canonical',
            href: getCanonicalPath(route.path),
        },
    ],
}))

解決までの流れ

Nuxt4でcanonicalを設定しようとしたとき、まず考えられるのがlayoutsディレクトリ配下に以下のような感じで配置することです。

素直にuseHeadへの記載

useHead({
    link: [
        {
            rel: 'canonical',
            href: 'https://example.com' + useRoute().path,
        },
    ],
});

これは上手くいきません。
最初にアクセスしたURLがcanonicalには設定され、その後ページ遷移しても設定値は変わりません。
(最初 https://example.com にアクセスして、その後 https://example.com/hoge  にアクセスしてもcanonicalは https://example.com  のままになります。)
ちょっとNuxtのライフサイクルへの理解が怪しいので、あってるか自信がありませんが、layouts内の内容は最初にレンダリングされてその後は同じ内容を使いまわすようになっているので、同じ値のままになるのだと思います。
(titleTemplate等例外はありますが。)

引数を関数で書く

ここでStackOverflowで海外のドンピシャ質問とドンピシャ回答を見つけます。

const route = useRoute()
useHead(() => ({
  link: [
    {
      rel: 'canonical',
      href: 'https://example.com' + route.path,
    },
  ],
}))

理屈が書かれていないので私のような人間には何故こうなっているのかきちんとわかってませんが、
同じくuseHeadの titleTemplate と同じような仕組み(こちらも動的にタイトルタグを設定できる)なのかなと思ってます。

これで解決かと思いましたが、今度は Googleサーチコンソールに「ページが重複しているよ」と言われ、URL末尾に「/」(スラッシュ)つけるかつけないか問題を発見します。
(以下のようなURLで違うURLで同じページに遷移できてしまい、かつカノニカルも別々になっていました。)

設定時に末尾にスラッシュがあるか見て除去する関数をかませる

ここまで来たらもう解説は不要かもしれませんが、URLを見て末尾にスラッシュがあるかをendWith関数で判断し、除去する(自分はこっちを採用)。もしくはスラッシュが存在しなければスラッシュを付与する。のどちらかの処理を行ってからカノニカルを設定するだけでOKです。結論のコードに戻ります。

所感

Canonical URLを共通の処理で設定するだけなのですが、意外とハマってしまったので備忘録として残しておきます。

    • BlueSkyで共有する
    • Hatenaで共有する
記事の作成者のW.Aのアイコン

この記事を書いた人

W.A
茨城県在住Webエンジニアです。 PHP、PostgreSQL、Linuxなどを業務で使用しています。 趣味ではGoやNuxt、Flutterをやってます。
  • GitHubのリンク

Comment

関連記事

  • Nuxt4にCKEditor5を追加するのサムネイル画像

    Nuxt4にCKEditor5を追加する

    掲載

    2026年最新のNuxt環境におけるCKEditor 5の導入・設定方法の備忘録です。基本的なインストール方法と、2026年5月現在出ているエラーを回避する各エディタ(インライン等)のインスタンス生成手順をまとめています。

  • Nuxt4とd3.jsでインタラクティブな日本地図を作るのサムネイル画像

    Nuxt4とd3.jsでインタラクティブな日本地図を作る

    掲載

    Nuxt4とd3.jsで国土地理院のデータをもとにインタラクティブな日本地図を描画して、各都道府県のsvg画像を取得できるツールを作成した際の実装の解説です。国土地理院のデータをmapshaperで軽量化することで、Webページの表示を軽くするなどの工夫についても解説。実際に作ったツールを利用することも可能です。(※国土地理院のデータは利用時に出典を明記する必要があるのでご注意ください。)

  • Nuxt4でプログラム可能な検索エンジンを組み込むのサムネイル画像

    Nuxt4でプログラム可能な検索エンジンを組み込む

    掲載

    サイト内に検索機能を追加するために、Googleのプログラム可能検索エンジンを使用しました。Googleのプログラム可能検索エンジンの設定画面側で何を設定するのかと、Nuxtでサイト内に検索枠と検索結果を表示する方法を実際のコード付きで解説しています。外部の検索ツールを使用することによる、実装コストが低い等のメリットや、記事を登録して即時に反映はされないといったデメリットもあわせて記載しています。

check コピーしました!