【Laravel】サイトマップを動的に作成したい

#Laravel
writtdden by ま。

こんにちは、ま。です

Webサイトを作る際に絶対に用意するであろうサイトマップ。毎回書くのはめんどくさいですよね。
なんとか、アクセスするたびに最新のものが表示されるようにできないかなぁーと思って調べたので、まとめてみます。

パッケージインストール

laravel-sitemap を利用します。

composerでインストールしてあげます。

composer require laravelium/sitemap
php artisan vendor:publish --provider="Laravelium\Sitemap\SitemapServiceProvider"

上記コマンドでインストールすると最新版がインストールされるので、場合によってはエラーが出るかもしれません。
ご利用のlaravelバージョンに合わせてパッケージバージョンを指定してあげてください。

#laravel8
composer require laravelium/sitemap 8.*

#laravel7
composer require laravelium/sitemap 7.*

laravel-sitemapの使い方

// サイトマップオブジェクとの生成
$sitemap = App::make("sitemap");
// URLを追加
$sitemap->add(URL::to('/'), now(), '1.0', 'always');
// 表示
return $sitemap->render('xml');

使い方はこれだけです。
URL追加の引数についてだけ先に説明しておきます。

・URL::to()で登録したいURLを指定してあげます。
・now()は最終更新の指定です。
・1.0は優先度です。0.1~1.0で指定します。(Googlebot的には関係ないらしい)
・alwaysは更新頻度です。alwaysの他にweeklyとmonthlyがあります。

コントローラーの作成

今回はコントローラーに全部書いてしまいますが、DBアクセスなどはコントローラーに書かないよって場合は切り分けてください。

namespace App\Http\Controllers;
use Illuminate\Support\Facades\App; 
use Illuminate\Support\Facades\URL;

class SitemapController extends Controller { 
    public function index(Request $request) {  
       
        $sitemap = App::make("sitemap");
        // Topページ
        $sitemap->add(URL::to('/'), now(), '1.0', 'always');
        
        // DBのデータを取得しaddしていく
        // 今回は仮に、https://ドメイン/detail?id=1 のようにページが存在するものとします。
        $posts = Post::query()->orderBy('updated_at', 'desc')->get();
        foreach ($posts as $post) {
            $sitemap->add(URL::to('/detail?id=' . $post->id), $post->updated_at, '0.8', 'monthly');
        }

        // 出力
        return $sitemap->render('xml');
        // XMLファイルで出力する場合
        // $sitemap->store('xml', 'mysitemap');
    }
}

ルーティング設定

routeを設定します。
他のページと同じようにhttps://ドメイン/sitemap.xmlにアクセスされた際の処理をweb.phpに記載します。

Route::get('/sitemap.xml', 'App\Http\Controllers\SiteMapController@index');

これで、sitemap.xmlにアクセスしてみてください。
最新のサイトマップが表示されているはずです。

URL件数が多い場合

サイトマップには登録数5万件までという制約があったりしますし、ページごとにサイトマップを分けることで管理しやすくしたりします。

そこで動的にする際も件数が多い配慮をしておきたいところです。
ただ調べてみてもlaravel-sitemapではサイトマップ内にサイトマップのURLを書くことはできなさそうです。

仕方がないのでそういった場合はルートとなるサイトマップだけ用意してあげてください。
後述しますがサイトマップに登録するURL件数の最大数を指定しておくと、その件数を超えた際にsitemap-0.xml、sitemap-1.xmlとローテートしてくれます。

おわりに

めちゃくちゃ簡単に実装できました。
動的にするとデータが増えるたび追加する必要がないのでとても楽ですね。

ちなみにサイトマップのページは
public/vendor/sitemap/styles/xml.xsl
をテンプレートに生成されています。余計な文章が表示されたりしているので、いらないなって場合はこちらを編集してあげてください。

また、config/sitemap.phpというファイルがパッケージをインストールすると作成されています。
1つのサイトマップに登録する数の指定だったり、テンプレートデフォルトでスタイル指定されてたりしますが、そういった設定ができます。あんまり設定する必要はないですが笑

Laravel関連記事

【Web開発】Docker+Nginx+PHP(laravel)で開発環境構築をする手順

【Laravel】名前付きルートの実装方法

Favorite