Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Sitemappable Laravel Package

vursion/laravel-sitemappable

A Laravel package that makes Eloquent models sitemappable, letting you generate XML sitemaps directly from your models with configurable URLs, last-modified dates, priorities, and change frequencies for better search engine indexing.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and start with the smallest useful flow: generate a sitemap for a known set of public URLs.

composer require spatie/laravel-sitemap

Optionally publish config if you need to tune crawling behavior:

php artisan vendor:publish --provider="Spatie\Sitemap\SitemapServiceProvider"

A minimal crawl-based sitemap:

use Spatie\Sitemap\SitemapGenerator;

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

A minimal model/URL-driven sitemap:

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

Sitemap::create()
    ->add(Url::create('/'))
    ->add(Url::create('/about'))
    ->writeToFile(public_path('sitemap.xml'));

Look first at Spatie\Sitemap\Sitemap, SitemapGenerator, Tags\Url, and the Sitemapable contract. If you add Eloquent models, the 1.12.0 release is relevant: model created_at and updated_at timestamps are now persisted onto sitemap entries, so model-driven sitemaps can carry meaningful <lastmod> data without a separate lookup.

First practical use case: create an artisan command that builds a sitemap for your public marketing pages, blog posts, and product pages, writes it to public/sitemap.xml, and schedules it daily.

Implementation Patterns

Crawl-driven sitemaps
Use SitemapGenerator when you do not already have a clean URL source. Configure crawl limits and profiles before running it, and execute it from a command or queue job rather than a web request.

SitemapGenerator::create(config('app.url'))
    ->setMaximumCrawlCount(500)
    ->writeToDisk('public', 'sitemap.xml');

Route/manual sitemaps
Use Sitemap::create()->add(Url::create(...)) for known routes. Set metadata explicitly where it matters:

Url::create(route('posts.show', $post))
    ->setLastModificationDate($post->updated_at)
    ->setChangeFrequency(Url::CHANGE_FREQUENCY_WEEKLY)
    ->setPriority(0.8);

Model-driven sitemaps
Implement Sitemapable on models you want to add directly:

use Spatie\Sitemap\Contracts\Sitemapable;
use Spatie\Sitemap\Tags\Url;

class Post extends Model implements Sitemapable
{
    public function toSitemapTag(): Url|string
    {
        return Url::create(route('posts.show', $this));
    }
}

Then add a filtered collection:

Sitemap::create()
    ->add(Post::query()->published()->get())
    ->writeToFile(public_path('sitemap.xml'));

With 1.12.0, the model’s created_at and updated_at are available on the resulting sitemap entry. Use this to drive <lastmod> from updated_at instead of duplicating date logic. Check the generated XML in your application to confirm whether your Sitemapable return value or the package sets <lastmod> in your exact setup.

Sitemap indexes and chunking
For large sites, split entries into multiple sitemap files and reference them from a sitemap index. Keep each sitemap below the protocol limits: 50,000 URLs and 50 MB uncompressed.

Scheduling and serving
Generate on a schedule, write to a public disk, and serve the file through a route or web server. A common pattern is a scheduled command writing public/sitemap.xml, plus a lightweight route returning it with application/xml.

Testable generation
Extract sitemap construction into a service or command. In tests, generate to a temporary path, assert the file exists, and parse the XML to assert expected URLs and <lastmod> values.

Gotchas and Tips

  • Crawling is slow and can be unpredictable. Always set a maximum crawl count, respect robots/timeouts, and run generation from a queued job or scheduled command.
  • Sitemaps are not automatically served by Laravel. You must create a route, controller, or web server rule to expose the generated file.
  • lastmod should be a valid W3C datetime. Carbon instances generally work, but null timestamps should not produce a <lastmod> element.
  • The 1.12.0 timestamp persistence only helps models that actually have created_at/updated_at. Models with timestamps disabled or custom date columns need explicit handling.
  • Do not add every model row blindly. Scope queries to published, public, canonical URLs; otherwise drafts, duplicates, or private resources can leak into the sitemap.
  • Select only needed columns when adding large collections, e.g. select('id', 'slug', 'updated_at'), to avoid memory pressure.
  • Watch URL generation. route() and Url::create() depend on APP_URL, request context, and route model binding; verify the generated XML contains absolute production URLs.
  • Filesystem paths are a common failure point. writeToFile(public_path(...)) and writeToDisk('public', ...) behave differently; confirm disk configuration and permissions.
  • For large sites, use a sitemap index and chunked generation. A single huge Sitemap::create()->add($allModels) can exhaust memory.
  • When debugging, inspect the generated XML directly, then inspect the in-memory sitemap collection before writing. Crawler failures often need logging around SitemapGenerator.
  • Main extension points are custom Url tags, custom crawl profiles, Sitemapable implementations, and your own command/service layer around generation. Keep sitemap policy in application code rather than scattering it across controllers.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings