Next.jsのサイトマップ作成について
こんにちは、CURUCURUエンジニアの水谷です。 最近のタスクでサイトマップ作成に絶賛取り掛かり中です。
Next.jsを利用したサイトマップ作成についてまとめようと思います。 現在作成中なので完成時には異なるかもしれないですが、現状の困っていることや作成すべき機能についてまとめておこうと思います。
概要
Next.jsを利用したECサイトのサイトマップ作成について
サイトマップとは
サイトマップには二種類あります。
- ・ユーザーに構成を伝えるもの
- ・検索エンジンに構成を伝えるもの
上記の二種類があり、今回は検索エンジンに構成を伝える場合で書いていきます。
主にXML形式が用いられますが、具体例としては下記のようなものです。
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://curucuru-select.com</loc>
<lastmod>2023-11-27T07:17:30.452Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
</urlset>
urlで囲まれてものがページごとに用意されます。
- loc:ページURL(最低限必要)
- lastmod:最終更新日時
- changefreq:ページの更新頻度
- priority:ページの優先度
lastmodに関してはページの更新が多く、クロールが必要な場合に設定します。 とはいえ、更新したからといって必ずしもクロールが来るわけではないです。
changefreqに関しても、次回クロールの目安くらいで、必ずしも指定通りにはなりません。 priorityは設定してもGoogleのクローラーは見ないらしいです。 https://www.suzukikenichi.com/blog/google-ignores-priority-but-uses-lastmod-in-sitemaps/
結論として、locだけあれば最低限良さそうです。
Next.jsのサイトマップ
では、これをNext.jsで作成していきます。 検索エンジンに構成を伝えるためにはサーバーサイドで用意する必要があります。 選択としては「SSR」もしくは「SSG」で用意します。
シンプルなのはSSGです。 XMLファイルと置いておけば完了です。
ただ、ECサイトの場合は、商品やブランド、カテゴリの掲載作業によってページの更新が多く発生します。 その度に生成するのも面倒なので、検索エンジンがアクセスしたタイミングでXMLのデータを作ってそれを返す方法が良いと思いました。
Next.jsのサイトマップをSSRで作成する
下記の方法で作成します。
- ・pages配下にsitemap.xml.tsxを作成する
- ・getServerSidePropsでxmlを生成して返す
書いたコードが下記です。
import { generageSitemapXml } from '../utils/sitemap';
import type { GetServerSidePropsContext } from 'next';
export const getServerSideProps = async ({ res }: GetServerSidePropsContext) => {
const xml = await generageSitemapXml();
res.statusCode = 200;
res.setHeader('Cache-Control', 's-maxage=86400, stale-while-revalidate');
res.setHeader('Content-Type', 'text/xml');
res.end(xml);
return {
props: {},
};
};
const SiteMapPage = () => null;
export default SiteMapPage;
このコードは下記サイトを参考にして書きました。 https://zenn.dev/catnose99/articles/c441954a987c24 ちょうど欲しかった情報だったので大変助かりました。
これを書くことによってサーバーサイドでXMLを作って動的に返すことができました。
サイトマップに必要なXMLのデータを作成する
サイトマップに必要なXMLのデータを作成します。
export const generageSitemapXml = async () => {
let xml = '<?xml version="1.0" encoding="UTF-8"?>\n';
xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n';
const mapDatas = await getAllMapData(props);
mapDatas.forEach((mapData) => {
xml += '<url>\n';
xml += `<loc>${host}${mapData.path}</loc>\n`;
xml += '</url>\n';
});
xml += pageSiteMap;
xml += '</urlset>';
xml = xml.replace(/&/g, '&');
return xml;
};
サイトマップアクセス時に、&がそのままだと読み取れないので、特殊文字で書いています。 getAllMapDataの中でブランドやカテゴリや商品のURLデータを配列として取得してきます。
そして、大元のサイトマップのデータは下記を使いました。 コマンドを打つだけで作成されるので便利です。 https://github.com/iamvishnusankar/next-sitemap
これで生成したマップに動的に作るマップを足していくイメージです。
これでアクセス時に動的に生成することができますね。
まとめ
パラメータを使ったURLを生成している場合、プラグインだけで取得できなかったりします。 バックエンド側でパラメータを管理していたりすると、サーバーサイドで一度取得が必要だったりして、そういうパターンでも使える方法でした。 特にECサイトとかでは便利かなと思います。
メンバー募集
CURUCURUでは開発メンバーを絶賛募集中です。 CURUCURUの開発に興味があったり、モダンな開発環境で挑戦してみたいという方がいましたら、ぜひこちらも覗いてみてください!