Sitemap(生成 XML 格式的 Sitemap)

spatie/laravel-sitemap

介紹

spatie/laravel-sitemap 是一個 Laravel 套件,用來自動產生 sitemap.xml 檔案,協助搜尋引擎(如 Google)更有效率地索引網站內容。

主要功能包括:

  • 產生 sitemap.xml 檔案
  • 可設定網址的:
    • 頻率(dailyweekly 等)
    • 優先順序(0.0 ~ 1.0
    • 最後更新時間
  • 可動態產生 sitemap(如從資料庫讀取)
  • 支援多個 sitemap 拆分(sitemap index

適用網站類型與原因如下:

網站類型 適用原因
部落格 自動列出所有文章頁面的 sitemap
電商網站 自動列出所有商品頁面的 sitemap
SPA 或自定義路由網站 可手動加入特定路由

安裝

composer require spatie/laravel-sitemap

基本使用方式

執行下列路由後,會在 public/sitemap.xml 產生 sitemap 檔案。

use Spatie\Sitemap\Sitemap;
use Spatie\Sitemap\Tags\Url;

Route::get('/generate-sitemap', function () {
    Sitemap::create()
        ->add(Url::create('/')->setPriority(1.0)->setChangeFrequency(Url::CHANGE_FREQUENCY_DAILY))
        ->add('/about')
        ->add('/contact')
        ->writeToFile(public_path('sitemap.xml'));

    return 'Sitemap 已產生!';
});

從資料庫自動建立 sitemap

use App\Models\Post;
use Spatie\Sitemap\Sitemap;
use Spatie\Sitemap\Tags\Url;

Route::get('/generate-sitemap', function () {
    $sitemap = Sitemap::create();

    Post::all()->each(function ($post) use ($sitemap) {
        $sitemap->add(
            Url::create("/posts/{$post->slug}")
                ->setLastModificationDate($post->updated_at)
                ->setChangeFrequency(Url::CHANGE_FREQUENCY_WEEKLY)
                ->setPriority(0.8)
        );
    });

    $sitemap->writeToFile(public_path('sitemap.xml'));

    return '文章 sitemap 已產生';
});

sitemap index(進階)

若網站頁面超過 Google 的限制(單個 sitemap 最多 50,000 條 URL 或最大 50MB),建議拆成多個 sitemap 並建立 sitemap index:

use Spatie\Sitemap\SitemapIndex;

SitemapIndex::create()
    ->add('/sitemap-posts.xml')
    ->add('/sitemap-pages.xml')
    ->writeToFile(public_path('sitemap.xml'));

額外功能一覽

方法 說明
setLastModificationDate() 指定該網址最後修改時間
setChangeFrequency() 指定搜尋引擎多久應重新爬取該頁面
setPriority() 指定該網址的相對重要性,0.0 ~ 1.0
Url::create() 建立 URL 並可設定 tag 屬性(支援完整自訂)

Artisan 指令自動產生 sitemap.xml

建立指令

php artisan make:command GenerateSitemap

編輯指令邏輯

// app/Console/Commands/GenerateSitemap.php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Spatie\Sitemap\Sitemap;
use Spatie\Sitemap\Tags\Url;
use App\Models\Post;

class GenerateSitemap extends Command
{
    protected $signature = 'sitemap:generate';
    protected $description = '產生 sitemap.xml 檔案';

    public function handle(): int
    {
        $this->info('產生 sitemap 中...');

        $sitemap = Sitemap::create();

        // 固定頁面
        $sitemap->add(Url::create('/')
            ->setPriority(1.0)
            ->setChangeFrequency(Url::CHANGE_FREQUENCY_DAILY)
        );

        $sitemap->add(Url::create('/about')->setPriority(0.7));
        $sitemap->add(Url::create('/contact')->setPriority(0.7));

        // 動態資料:所有文章
        Post::all()->each(function ($post) use ($sitemap) {
            $sitemap->add(
                Url::create("/posts/{$post->slug}")
                    ->setLastModificationDate($post->updated_at)
                    ->setChangeFrequency(Url::CHANGE_FREQUENCY_WEEKLY)
                    ->setPriority(0.8)
            );
        });

        // 寫入 sitemap.xml
        $sitemap->writeToFile(public_path('sitemap.xml'));

        $this->info('✅ sitemap.xml 已成功產生!');

        return Command::SUCCESS;
    }
}

註冊指令

// app/Console/Kernel.php
protected $commands = [
    \App\Console\Commands\GenerateSitemap::class,
];

執行方式

php artisan sitemap:generate

加入排程(選用)

// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    $schedule->command('sitemap:generate')->daily();
}