目次
laravel-sitemapというライブラリを使用してLaravelアプリケーションにサイトマップを導入します
(追記) もっと分かりやすくまとめました
laravel-sitemapをインストールする
最新版はGitLabにあるらしい
https://gitlab.com/Laravelium/Sitemap
で、インストールしようとしたのだが以下の様にGitLabの認証が必要と言われてインストール出来ない。
Cloning failed, enter your GitLab credentials to access private repos
いろいろ試しているとLaravel 6.x, 7.x 対応のバージョンだと認証なしでダウンロードできる様だが、5.x対応のバージョンだとGitLab認証が求められてしまう模様
本番環境のコンテナは自動ビルドなので認証求められるのは辛い・・・。
これは本ライブラリの仕様なのか設定ミスなのかよくわからないが一旦見送る。
もう1つのライブラリ
サイトマップを生成するライブラリはもう一つ、spatie/laravel-sitemapというのがあって、英語で検索するとこちらのほうが検索上位だったりする。
packagistのインストール数もspatie/laravel-sitemapの方が多い
spatie/laravel-sitemapをインストールする
という訳でspatie/laravel-sitemapをインストールします。
readmeを読んでいて気づいたのだが、このライブラリはサイトをクロールしてサイトマップを作ってくれるらしい。
設定すればJavaScriptも実行してリンクを辿るとの事。
ちなみに以下のコードでクロールできる。
use Spatie\Sitemap\SitemapGenerator; SitemapGenerator::create('https://example.com')->writeToFile($path);
どうやって実行するかには言及されていないので、コマンドを作って毎日n時に実行とかしとけばOKだろ(多分)
という訳でコマンドを作って実行してみた。
class SitemapGeneratingCommand extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'sitemap:generate'; /** * The console command description. * * @var string */ protected $description = 'Command description'; /** * Execute the console command. * * @return mixed */ public function handle() { $path = Storage::disk('local')->path('sitemap.xml'); SitemapGenerator::create(config('app.url'))->writeToFile($path); } }
php artisan sitemap:generate
そして出力されたのがこちらのxml
空なんだが・・・?
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
</urlset>
あー。この処理を実行するdockerコンテナ内の/etc/hosts
にはドメインが記載されていないから、ローカル環境はクロールできないか。
本番環境のURLを指定したら一応、動いた。
対象のサイトはJavaScriptゴリゴリなので、全然リンクが拾えてない。
config/sitemap.php
のexecute_javascript
をtrueにするとJSも処理されるらしいので有効にして再実行してみる。
以下のエラーが発生した。
どうやらnpmとnodeに依存しているらしい。(nodeからbrower.jsを実行しようとしている)
Symfony\Component\Process\Exception\ProcessFailedException : The command "PATH=$PATH:/usr/local/bin NODE_PATH=`npm root -g` node '/var/www/app/vendor/spatie/browsershot/src/../bin/browser.js'
...(略)...
Error Output:
================
sh: npm: not found
sh: node: not found
うーん、このためだけにコンテナにnodeとnpmを追加するの微妙だな・・・。
ARCANEDEV/LaravelSitemapを導入する。
ARCANEDEV/LaravelSitemapというライブラリもあって、こちらはシンプルにxmlを構築できるだけっぽい。
packagistのインストール数も上記2つほど多くない。
というわけでこちらを入れてみる。
Laravelのレスポンスを構築してくれるのでControllerにこんな感じで書ける
public function posts() { $manager = new SitemapManager(); $map = Sitemap::make()->setPath(action('SitemapController@posts')); Post::all()->each(function (Post $discussion) use ($map) { $url = action('PostController@read', [ 'discussion' => $discussion->id ]); $map->create($url, function (Url $url) use ($discussion) { $url->setLastMod($discussion->updated_at) ->setChangeFreq('weekly') ->setPriority(1.0); }); }); $manager->add('dummy', $map); return $manager->respond(); }
で、実際にURLを開いたら以下のエラーが出た・・・。
No hint path defined for [sitemap]
以下の箇所で、viewsの名前空間sitemap
にアクセスしているが、名前空間がちゃんと登録されていないためエラーが発生している。
publish
もやっていてresources/views/vendor/sitemap
も存在するのに何故・・・?
php artisan vendor:publish --provider="Arcanedev\LaravelSitemap\LaravelSitemapServiceProvider"
Laravel 5.x系なのでライブラリ側がちゃんと対応できてないのかも。
一応、AppServiceProvider
のboot
メソッドに以下を追記してやると、viewsの名前空間が登録されて、上記のエラーが回避できる。
今回はこれで回避する事にした。(ここまでさんざん他のライブラリにもハマって来たので心が折れた)
$this->loadViewsFrom(resource_path('views/vendor/sitemap'), 'sitemap');
紆余曲折ありつつも、sitemap.xmlが取得できる状態になった。
robots.txtにサイトマップのパスを記述する
/public/robots.txt
に追記する
User-agent: *
Disallow:
Sitemap: https://your-domain/sitemap.xml
Search Consoleにサイトマップを登録する
サイトマップの登録おわり!
ライブラリ選定で時間掛かりすぎて肝心のサイトマップの内容をやっつけで作ってしまった。
近いうちに見直す!
Webエンジニアをやっています
UX/UIデザインからプログラミング、DB設計、SEO、インフラ構築など幅広く対応してます
PHP/PHPUnit/Laravel/Vue/Nuxt/Docker/Terraform
ご連絡はTwitterのDMまで。
「Laravelアプリケーションにサイトマップを導入する」への1件のフィードバック