ログオフ
開発2026-06-20

Next.js で sitemap.xml が二系統できる:app/sitemap.ts と next-sitemap の競合

App Router の app/sitemap.ts に動的ロジックを書いたのに反映されない。next-sitemap を併用すると sitemap.xml が二系統になり、public/ の静的ファイル側が配信されることがある。

App Router の app/sitemap.ts にロジックを書いたのに、配信される sitemap.xml が想定と違う。原因は sitemap の生成元が二系統あることだった。

事象

  • app/sitemap.ts で動的にURLを組んだのに、本番の /sitemap.xml に反映されない
  • 期待した内容と違う sitemap が返ってくる
  • ビルドは通るし、エラーも出ない

原因

sitemap を作る仕組みが 2 つ同居していた。

  • app/sitemap.ts:App Router の機能。/sitemap.xml をリクエスト時に生成するルート
  • next-sitemap:ビルド後(postbuild)に public/sitemap.xml を書き出すライブラリ

両方入れると、/sitemap.xml というパスに対して「動的ルート」と「public 配下の静的ファイル」がぶつかる。静的ファイルが配信されると、app/sitemap.ts に書いた動的ロジックは出てこない。「sitemap.ts を直したのに変わらない」の正体はこれだった。

解決策

どちらか一方に寄せる。App Router を使っているなら app/sitemap.ts に統一するのが素直だ。

next-sitemap をやめる場合:

// package.json から postbuild を消す
{
  "scripts": {
    // "postbuild": "next-sitemap"  ← 削除
  }
}

そのうえで public/sitemap.xmlpublic/sitemap-*.xmlpublic/robots.txt(next-sitemap が吐いたもの)を消す。public/ に残っているとそちらが優先されてしまう。

確認は本番の /sitemap.xml を実際に開いて、app/sitemap.ts の出力になっているかを見る。

補足

  • 逆に next-sitemap に寄せる選択もあるが、動的にURLを組みたいなら App Router 側の方が書きやすい
  • robots.txt も同じ構図になりうる。app/robots.ts と next-sitemap の robots 生成が二重化していないか合わせて確認する

※ 本記事にはアフィリエイトリンクが含まれます。

開発 一覧へ