Skip to content

Sitemap ​

Use an explicit URL list for the public pages from Page Stubs. It avoids crawling auth routes and does not depend on Svelte-rendered links being visible to a crawler.

Run commands in the Laravel application. Set APP_URL to the canonical site URL before generating the production file.

Install ​

bash
composer require spatie/laravel-sitemap

The package does not register sitemap:generate; define that command below before running or scheduling it.

Generate the Sitemap ​

File: routes/console.php (merge with existing commands and schedules)

php
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schedule;
use Spatie\Sitemap\Sitemap;
use Spatie\Sitemap\Tags\Url;

Artisan::command('sitemap:generate', function (): void {
    Sitemap::create()
        ->add(Url::create(url('/')))
        ->add(Url::create(url('/about')))
        ->add(Url::create(url('/contact')))
        ->add(Url::create(url('/privacy')))
        ->add(Url::create(url('/terms')))
        ->writeToFile(public_path('sitemap.xml'));
})->purpose('Generate the public sitemap');

Schedule::command('sitemap:generate')->daily();

Keep only public, canonical, indexable URLs. Add published content URLs from the database when those models exist; do not include drafts, admin, login, or account pages.

bash
php artisan sitemap:generate

Ensure the application can write public/sitemap.xml. Generate after deployment too if the public directory is replaced between releases.

Crawling Alternative ​

For a site with server-rendered links, replace the command body with a crawl:

php
use Spatie\Sitemap\SitemapGenerator;

// Inside sitemap:generate:
SitemapGenerator::create(config('app.url'))
    ->writeToFile(public_path('sitemap.xml'));

The site must be reachable from the machine running the command. Client-rendered Inertia links may not be discovered without JavaScript execution; keep the explicit list unless crawling is actually needed.

Use the package's URL filtering options when crawling. Excluding a URL from the sitemap does not restrict access to it.

Schedule and Robots ​

The daily schedule still needs Laravel's scheduler running: schedule:work locally or the server's once-per-minute schedule:run entry.

File: public/robots.txt (append with the real production domain)

text
Sitemap: https://example.com/sitemap.xml

Verify ​

bash
php artisan sitemap:generate
xmllint --noout public/sitemap.xml
php artisan schedule:list

Open /sitemap.xml and check that every URL is absolute, uses the production host/scheme, and resolves to the intended public page. Do not publish a sitemap containing .test or localhost URLs.

References ​