Laravel 默认不生成 Sitemap,因其专注路由和响应,而 Sitemap 属 SEO 静态资源;动态内容需用 spatie/laravel-sitemap 手动添加 URL 并定时生成至 public/sitemap.xml。

为什么 Laravel 默认不生成 Sitemap?
Laravel 本身不内置 sitemap.xml 生成逻辑,它专注路由和响应,而 Sitemap 是 SEO 层面的静态/半静态资源。直接写死 XML 文件无法应对动态内容(如新发布的文章、商品),所以得靠手动触发或定时任务生成——但别用视图渲染 XML,容易出格式错误或编码问题。
用 spatie/laravel-sitemap 扩展包最稳妥
社区主流方案是 spatie/laravel-sitemap,它专为 Laravel 设计,支持 Eloquent 模型自动映射、多语言 URL、优先级与更新频率控制,且能直接写入 public/sitemap.xml,无需额外路由或中间件拦截。
- 安装:
composer require spatie/laravel-sitemap
- 发布配置(可选):
php artisan vendor:publish --provider="Spatie\Sitemap\SitemapServiceProvider" --tag=config
- 在
App\Console\Commands\GenerateSitemap中调用:
use Spatie\Sitemap\SitemapGenerator;
SitemapGenerator::create('https://yoursite.com')
->hasCrawled(function (string $url) {
return ! str_contains($url, '/admin') && ! str_starts_with($url, 'https://yoursite.com/api/');
})
->writeToFile(public_path('sitemap.xml'));
注意:hasCrawled 是关键过滤器,否则会把后台、API 路由也扫进去;writeToFile 必须指向 public/ 下,否则 Nginx/Apache 无法直接访问 /sitemap.xml。
动态内容必须显式添加,不能只靠爬取
包默认的 create() 是基于 HTTP 爬虫,对 Laravel 的 POST 路由、带参数的资源路由(如 post/{slug})基本无效。真实项目中,90% 的有效链接得手动加:
网趣购物系统静态版支持网站一键静态生成,采用动态进度条模式生成静态,生成过程更加清晰明确,商品管理上增加淘宝数据包导入功能,与淘宝数据同步更新!采用领先的AJAX+XML相融技术,速度更快更高效!系统进行了大量的实用性更新,如优化核心算法、增加商品图片批量上传、谷歌地图浏览插入等,静态版独特的生成算法技术使静态生成过程可随意掌控,从而可以大大减轻服务器的负担,结合多种强大的SEO优化方式于一体,使
use Spatie\Sitemap\SitemapGenerator;
use Spatie\Sitemap\Tags\Url;
$sitemap = SitemapGenerator::create('https://yoursite.com')->getSitemap();
// 添加首页
$sitemap->add(Url::create('/')->setLastModificationDate(now())->setChangeFrequency('daily')->setPriority(1.0));
// 添加文章列表页(假设用分页)
$sitemap->add(Url::create('/blog')->setLastModificationDate(now()->subDay()));
// 添加每篇已发布的文章
App\Models\Post::published()->each(function (App\Models\Post $post) use ($sitemap) {
$sitemap->add(Url::create($post->url)
->setLastModificationDate($post->updated_at)
->setChangeFrequency('weekly')
->setPriority(0.8)
);
});
$sitemap->writeToFile(public_path('sitemap.xml'));
重点:$post->url 必须返回完整路径(如 /blog/my-first-post),不能是相对路径或带域名的绝对 URL;setLastModificationDate 推荐用模型字段而非 now(),否则每次生成都变,不利于缓存识别。
生成时机:别在请求中实时生成
用户访问 /sitemap.xml 时再生成,会导致首屏延迟、并发下重复写文件、甚至生成损坏的 XML。正确做法是:
- 用 Artisan 命令 + 定时任务(如 Linux
cron)每天凌晨执行:php artisan sitemap:generate
- 在文章发布/更新后主动触发一次:
Artisan::call('sitemap:generate');(放在模型事件或控制器末尾) - 确保 Web 服务器(Nginx/Apache)将
/sitemap.xml请求直接映射到public/sitemap.xml文件,不走 PHP-FPM —— 否则可能 404 或返回 HTML 模板
如果用了 Cloudflare 或 CDN,记得设置缓存规则:对 /sitemap.xml 设置较长的 TTL(如 24 小时),但开启「缓存忽略查询参数」并禁用「自动压缩」,避免 XML 被 gzip 错误截断。









