Picture of the author

Next.js ver14でのSitemap.xmlの作成方法

ganeysa

sitemap.xmlとは?

Webサイトの構造をGoogleやBingなどの検索エンジンに伝えるためのXMLファイルです。検索エンジンがWebサイトの新しいページや更新されたページを効率的に発見し、インデックス化できるようになります。

上記の説明はclaude 3による説明です。

下に上の説明の分かりにくいところを簡単に補足しておきます。

XML:データ構造を記述するためのフォーマットのようなものでタグ付けすることでデータ構造を記述する物

具体例

<社員>
  <名前>山田太郎</名前>
  <年齢>35</年齢>
  <部署>
    <名称>営業部</名称>
    <所在地>東京</所在地>
  </部署>
</社員>

インデックス化:検索エンジン(Googleなど)にwebページを登録して検索に表示されるようにする事

sitemap.xmlの作成方法

①そのまま自分でXMLファイルを記述する

この方法だと時間がかかる!さらにAPIを用いて,CMSから記事の取得などをする構成のサイトなどではこれではsitemapを管理するコストが高くなるためおすすめしません!

②sitemap.js/tsを利用して作成する

これは,Next.jsでは①の方法をもちいなくてもコードを元に簡単に自動でsitemap.xmlを出力することができます

作成手順(sitemap.js/ts)

今回説明するのは,TypeScriptのコードではなく,JavaScriptのコードベースに説明します!(appルーティング)

①script.jsファイルを作成する

appディレクトリ直下にscript.jsファイルを作成してください!

プロジェクト名/app/script.js ← おそらくこんな感じのpathになると思います~

②script.jsファイル内のスクリプトを作成する!

静的なpathのみの場合!

静的なpathの場合は,以下のようなコード例を書いてもらうとxmlファイルを出力例のように出力する事が できます!

コード例

export default function sitemap() {
  return [
    {
      url: 'https://acme.com',
      lastModified: new Date(),
      changeFrequency: 'yearly',
      priority: 1,
    },
    {
      url: 'https://acme.com/about',
      lastModified: new Date(),
      changeFrequency: 'monthly',
      priority: 0.8,
    },
    {
      url: 'https://acme.com/blog',
      lastModified: new Date(),
      changeFrequency: 'weekly',
      priority: 0.5,
    },
  ]
}

出力例

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://acme.com</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>yearly</changefreq>
    <priority>1</priority>
  </url>
  <url>
    <loc>https://acme.com/about</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://acme.com/blog</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.5</priority>
  </url>
</urlset>

コード例の解説

{
      url: 'https://acme.com',
      lastModified: new Date(),
      changeFrequency: 'yearly',
      priority: 1,
 },

urlには指定したいpathを指定してください!

lastmodifiedは特に変更する必要はありません。

changeFrequencyとpriorityはGoogle公式によると無視されるそうなのであんまり関係ないかも?

上記リンクより引用

{}で囲まれた部分をワンセットとして静的なURLの数だけ作成してください もし面倒だったらpathを格納した配列を作成してmap関数やfor文などで処理した値をretrunすると良き!

※補足

静的なpath:変化しないpath名のことである。

動的なpathがある場合!(ダイナミックルーティングのページのsitemap作成)

ダイナミックルーティングのような変化する動的なpathを用いたsitemapを作成するには,基本的にはまず動的なpathを作成するためのIDなどを取得する処理はしそれをmap関数,for文などで取得した数だけ実行し先ほど説明した静的pathの時のurlの部分の登録をしていく形になります。説明ではわかりづらいと思うので下にコード例をしめしていきます。

コード例

import {  getAllPosts } from "@/lib/notion/notion"

const domain = "https://ganesyatech.com/"

export default async function sitemap() {
  //ここはデータを持ってくる関数ならなんでもいい
    const allData = await getAllPosts();
  
    const dynamicPaths = allData.map((data) => {
    return {
     
      url: `${domain}/blog/${data.uuid}`,
      lastModified: new Date(),
      changeFrequency: 'monthly',
      priority: 0.5,
      
    }

    
  });
  
  return [ ...dynamicPaths]

  }

コードの解説

それでは上から順にコードの解説をしていきます!

1行目ではまず今回のコードでは,notionAPIを用いてデータを取得する関数をimport してきています。 皆さんがこのコードを参考にsitemapを作成する際は,別途ちがうロジックでデータをもってくる処理を記述してimportしてください。

3行目では変数domainに今回sitemapを作成するドメイン名を設定しています。 この変数を利用することであとで楽することができるので宣言しています!

5行目以降では,非同期関数としてsitemapを宣言しています

そして内部では先ほどimport してきた関数getAllPostを利用してデータをすべて取得してそのデータをmap関数で回すことでその中のuuid(ID)を動的ルーティングのblog/[id]の[id]の部分としているのでこれを[id]の部分に data.uuidを代入することでsitemapを生成していきます!

補足 動的path+静的path を生成するsitemap.js

さきほど説明した両方を組み合わせたsitemap.jsです!ぜひご参考にしてください~

import { getAllPosts} from "@/lib/notion/notion"

//domain変更の時は,ここを変更するのみで良き!
const domain = "https://ganesyatech.com/"

export default async function sitemap() {

    
    

    const staticPath =  [

      {
        url: `${domain}`,
        lastModified: new Date(),
        changeFrequency: 'daily',
        priority: 1,
      },

      {
        url: `${domain}/list/機械学習`,
        lastModified: new Date(),
        changeFrequency: 'weekly',
        priority: 0.8,
      },

      {
        url: `${domain}/list/読書メモ`,
        lastModified: new Date(),
        changeFrequency: 'weekly',
        priority: 0.8,
      },

      {
        url: `${domain}/list/ツール`,
        lastModified: new Date(),
        changeFrequency: 'weekly',
        priority: 0.8,
      },

      {
        url: `${domain}/list/アルゴリズム`,
        lastModified: new Date(),
        changeFrequency: 'weekly',
        priority: 0.8,
      },

      {
        url: `${domain}/list/セキュリティ`,
        lastModified: new Date(),
        changeFrequency: 'weekly',
        priority: 0.8,
      },

      {
        url: `${domain}/list/工作`,
        lastModified: new Date(),
        changeFrequency: 'weekly',
        priority: 0.8,
      },
      
      {
        url: `${domain}/list/プログラミング`,
        lastModified: new Date(),
        changeFrequency: 'weekly',
        priority: 0.8,
      },
      {
        url: `${domain}/list/その他`,
        lastModified: new Date(),
        changeFrequency: 'weekly',
        priority: 0.8,
      },

    ]
    //ここはデータを持ってくる関数ならなんでもいい
    const allData = await getAllPosts();
  
    const dynamicPaths = allData.map((data) => {
    return {
      url: `${domain}/blog/${data.uuid}`,
      lastModified: new Date(),
      changeFrequency: 'monthly',
      priority: 0.5,
      
    }

    
  });
  
  //スプレッド構文
 
  return [ ...dynamicPaths,...staticPath]

  }

return のスプレッド構文については下記をご参考にしてください!

参考