この記事では、Next.jsで静的サイトを生成(SSG)するべくビルドする時に自動的に sitemap.xml を生成する方法を紹介します。
SEO対策として欠かせない sitemap.xml ファイル。
Next.jsで静的サイトを生成する場合、このファイルを手動で作成・更新するのは面倒です。
特にページ数が多いサイトでは管理が大変になります。
npm のビルドスクリプトを拡張して、手間をかけずに常に最新のサイトマップを維持できる仕組みを作りましょう。
なぜsitemap.xmlが必要なのか
sitemap.xmlは検索エンジンに対してサイト内のURLを明示的に知らせるためのファイルです。
(この記事に辿り着いた方には釈迦に説法だと思いますが・・・)
- クローラーがサイト内の全ページを効率的に発見できる
- 更新頻度や優先度を指定できる
- 検索エンジンのインデックス登録を促進できる
- 特に大規模なサイトや、リンク構造が複雑なサイトで効果的
実装方法
本題です。
Next.jsプロジェクトでビルド時にsitemap.xmlを自動生成する手順の流れです↓↓↓
- プロジェクトのルートディレクトリに
scripts
フォルダを作成 scripts
フォルダ内にgenerate-sitemap.js
ファイルを作成package.json
のscripts
セクションにpostbuild
コマンドを追加
この方法では、npm run build
を実行すると、ビルド完了後に自動的にsitemap.xmlが生成されます。
postbuild
を指定しておくことで、ビルドの流れに乗せられるので非常に楽になります。
コード解説
まずは scripts/generate-sitemap.js
ファイルを作成しましょう。
余力があれば ts で作成してもいいですね。
/* eslint-disable @typescript-eslint/no-require-imports */
const fs = require('fs');
const path = require('path');
// サイトのドメインを設定
const DOMAIN = 'https://example.com';
// 静的に生成されるパスのリストを取得する関数
const getStaticPaths = async () => {
return [
'', // トップページ
'about', // About ページ
'blog/first-post', // ブログ記事1
'blog/second-post', // ブログ記事2
// 他のパスをここに追加
];
};
// 実行関数
(async () => {
const paths = await getStaticPaths();
// sitemap.xmlの内容を生成
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${paths
.map(
(url) => `
<url>
<loc>${DOMAIN}/${url}</loc>
</url>`
)
.join('')}
</urlset>`;
// 出力先のパスを設定し、ファイルを書き込む
const filePath = path.resolve('out', 'sitemap.xml');
fs.writeFileSync(filePath, sitemap.trim());
})();
getStaticPaths
関数では、サイト内のURLを配列として定義します。これをもとにsitemap.xmlが生成されます。
個別に定義したい場合はサンプルの通りで問題ないです。 動的に生成したい方は記事の後半へ。
また、sitemap.xmlは特定のXML形式に従う必要があります。 上記スクリプトでは、最小限の形式でURLリストを生成しています。
Google が認識するにはこれで最低限ですが、十分です。 私のサイトもこれで検索順位が落ちているとかはないです。
生成したsitemap.xmlは、Next.jsの静的出力先である out
ディレクトリに保存されます。
これにより、ビルド成果物と一緒にデプロイできますね。
package.jsonの設定
次に、package.json
ファイルの scripts
セクションに postbuild
コマンドを追加します。
{
"name": "my-nextjs-project",
"version": "0.1.0",
"scripts": {
"dev": "next dev",
"build": "next build",
"postbuild": "node scripts/generate-sitemap.js",
"start": "next start",
"export": "next export"
},
// その他の設定...
}
postbuild
は特別なスクリプト名で、build
コマンドが正常に完了した後に自動的に実行されます。
これにより、ビルド完了後にsitemap.xmlが生成されるようになります。
(補足)最低限動作するコードです。実際はエラーハンドリング等、実戦で利用する場合は改善を加えてくださいね。
動作確認
設定が完了したら、次のコマンドでビルドを実行します。
npm run build
ビルドが完了すると、out
ディレクトリに sitemap.xml
ファイルが生成されているはずです。
ブラウザで開いて内容を確認してみましょう。
応用例
動的なパス生成
実際のアプリケーションでは、静的に定義したパスではなく、動的に生成したいケースが多いと思います。
例えば、以下のような方法があります。
const getStaticPaths = async () => {
// ディレクトリの走査やDBからの取得など
const blogPosts = await fetchAllBlogPosts();
return [
'',
'about',
...blogPosts.map(post => `blog/${post.slug}`),
];
};
この方式は、ご自身のプロジェクトの構造に依存すると思うので適宜調整してみてください。
lastmod の追加
ページの最終更新日時を含めることで、より効果的なsitemapになります。
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${paths
.map(
(path) => `
<url>
<loc>${DOMAIN}/${path.url}</loc>
<lastmod>${path.lastModified}</lastmod>
</url>`
)
.join('')}
</urlset>`;
優先度と更新頻度の設定
sitemap.xmlでは、各URLの重要度や更新頻度を指定することも可能です。
厳密に設定したい場合は追加してみてください。 ただし、一律設定以上のことをしようとすると、少しスクリプトの工夫が必要になります。
<url>
<loc>https://example.com/important-page</loc>
<priority>0.8</priority>
<changefreq>weekly</changefreq>
</url>
おわりに
Next.jsでSSGサイトを構築する際に、ビルド時に sitemap.xml を自動生成する方法を紹介しました。
実際に私の開発した LAZY TOOLS (便利なツール集を無料で提供するサイト)というサイトも、この方式で sitemap.xml を生成するようにしています。
コメント