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 Sitemap Laravel Package

spatie/laravel-sitemap

Generate sitemaps for your Laravel site with ease. Crawl your entire site automatically or build sitemaps manually, add URLs with metadata like last modification dates, and split large crawls into multiple sitemap files.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • Laravel-native package with service-provider auto-discovery; no separate infrastructure, no external SaaS dependency, no API keys. It slots into an existing Laravel monolith as a thin generation layer.
  • Two distinct operating modes, which is the main architectural decision:
    • Crawler-driven (SitemapGenerator::create($url)) — walks the live site and discovers URLs. Fits legacy/irregular routing or apps where the URL space isn't cleanly derivable from models. It is also the higher-risk mode (see below).
    • Programmatic (Sitemapable contract on Eloquent models) — each model returns its Url/route. Deterministic, testable, cheap, and the correct default for content-driven applications.
  • Hybrid mode is supported and useful: crawl for the static/marketing surface, then .getSitemap()->add(...) for model-backed sections.
  • Native support for multi-file output (closure-based per-URL routing to file paths), sitemap indexes (sitemapIndexPath), and maxTagsPerSitemap() further splitting into numbered files — this maps well onto a content-type-per-sitemap strategy and gives per-section indexing visibility in Google Search Console.

Integration feasibility

  • composer require spatie/laravel-sitemap; optional config publish; no migrations, no schema changes, no auth surface. This is a low-blast-radius dependency.
  • Realistic effort: 2–3 days for a spike plus a single-sitemap baseline; 3–4 weeks elapsed for one engineer to reach fully automated, split, indexed, monitored, and GSC-verified output — the bulk of that is URL inventory work and SEO sign-off, not code.
  • Requires a writable target (public disk, or S3 via writeToDisk(..., public: true) in 7.1.0+) and a scheduler or queue worker for regeneration.

Technical risk

  • Self-crawl hazards (highest risk if crawler mode is chosen). The generator issues real HTTP requests against your own application. Expect collisions with WAF/bot protection, rate limiting, auth-gated routes, paginated or parameterized URLs, and non-canonical duplicates. In PHP-FPM/serverless environments, long crawls risk execution timeouts and partially written files.
  • Memory and scale. The sitemap is accumulated in memory before write. Sitemap protocol caps are 50,000 URLs / 50MB uncompressed per file; beyond that you must split and index. Programmatic generation is O(n) in memory too — for six-figure URL inventories, plan per-section generation rather than one global run.
  • lastmod correctness. A default now() was deliberately removed in 6.3.1, which is the right call but shifts responsibility to us: naive lastmod values degrade trust with crawlers. This is a correctness requirement, not a nice-to-have.
  • Transitive version coupling. Depends on spatie/crawler (v8 in 7.x) and symfony/dom-crawler 7. These constrain our PHP/Laravel upgrade windows and will surface as Renovate/Dependabot churn.
  • Feature gaps to verify, not assume: native hreflang/alternate-link emission, canonical de-duplication, automatic search-engine ping/submission (historically present, appears to have been removed), and robots.txt generation (out of scope).
  • Data caveat: the "0 dependents" figure is an artifact of GitHub dependency graphing for PHP packages distributed via Packagist; it should not be read as low adoption. 2.6k stars, active releases, and Spatie's maintenance record are the better signal.

Key questions

  1. How many routable, canonical URLs exist today — 5k, 50k, or 500k? This determines split strategy and whether crawler mode is viable at all.
  2. Is the site single-domain or multi-tenant/multi-domain? The package generates one sitemap per invocation; multi-tenant means N jobs and N index files.
  3. Is the site internationalized with locale-prefixed URLs requiring hreflang? If yes, confirm whether the package emits alternates or we need a custom tag/renderer.
  4. Does any indexable content sit behind authentication or a bot-blocking WAF? If so, crawler mode is disqualified.
  5. Who owns SEO acceptance — is there an SEO/content stakeholder to sign off on sitemap structure before launch?
  6. What is the current mechanism (SaaS generator, hand-rolled route, manual upload)? That defines the parallel-run and cutover plan.

Integration Approach

Stack fit

  • Target the 7.x line: Laravel 9/10/11, PHP 8.1+, spatie/crawler v8, symfony/dom-crawler 7. Confirm the exact support matrix against our pinned Laravel and PHP versions before committing.
  • If we are on an older Laravel/PHP combination, pin to 6.x and schedule a bump — do not fork.

Migration path

  1. Parallel run. Generate to a staging path (e.g. /sitemap-new.xml) while the existing sitemap remains live and referenced in robots.txt.
  2. Diff. Compare URL sets between old and new; reconcile every discrepancy — additions are usually routes we forgot, omissions are usually canonicalization wins.
  3. Cutover. Swap the Sitemap: directive in robots.txt to the new index, keep the old path returning a 301 or removing it cleanly.
  4. Verify. Resubmit in Google Search Console and watch "Discovered URLs" and per-file indexing coverage.

Compatibility considerations

  • Pin the package major to the Laravel major in composer.json; these move together and Spatie has historically added new Laravel support promptly.
  • Decide the storage target early: public_path() vs a Laravel disk. Disk + public: true is preferable for containerized deploys where the filesystem is ephemeral — otherwise the sitemap vanishes on redeploy.
  • Set explicit cache headers / CDN behavior for the sitemap path; a stale CDN edge copy silently serves an outdated sitemap.
  • Ensure generated files are excluded from version control and treated as build artifacts.

Sequencing

  1. Spike (2–3 days). Generate for one environment; validate XML against the sitemap schema; measure URL count, memory, and runtime; confirm canonical-only coverage.
  2. Baseline. Implement Sitemapable on core models; single sitemap to the public disk; add a smoke test asserting schema validity and a minimum URL count.
  3. Split and index. Introduce the per-URL closure to route content types to separate files; add sitemapIndexPath; set maxTagsPerSitemap() for oversized sections.
  4. Automation. Scheduled Artisan command (or queued job if crawler mode), post-deploy trigger, and failure alerting.
  5. Launch. robots.txt update, GSC submission, baseline metrics captured.
  6. Extensions (optional, deferred). Image tags, video tags, Google News tags — only where the content types justify them.

Operational Impact

Maintenance

  • MIT-licensed, actively released, with a maintained changelog, docs site, and CI (tests, PHPStan, code style). Ongoing effort is low: dependency bumps on Laravel/PHP major upgrades, and periodic review of SEO output.
  • The real maintenance cost is not the library, it is the URL inventory contract — every new content type or route family needs an owner and a Sitemapable implementation, or it silently never gets indexed.

Support

  • GitHub issues only; no SLA, no vendor escalation path. Spatie offers paid support/consulting separately but it is not bundled.
  • Assign internal ownership explicitly: recommend the backend/platform team owns generation and scheduling, with SEO/content as the consuming stakeholder for output quality. Without a named owner, this becomes orphaned infrastructure that fails quietly.

Scaling

  • Hard protocol ceilings (50k URLs / 50MB per file) mean the design must be split-and-index from the start for any non-trivial site — retrofitting later is disruptive.
  • Crawler mode scales with site size and is the operational bottleneck; programmatic generation over indexed model queries scales far better and is cheaper to run.
  • Generation cost is per-run, full-corpus. For very large inventories, generate per content section on independent schedules rather than one nightly monolith.

Failure modes and mitigations

Failure Symptom Mitigation
Crawl timeout / partial run Truncated sitemap, silently written Assert minimum URL count; fail the job loudly
WAF / bot protection blocks crawler Empty or near-empty sitemap Allowlist crawler UA, or use programmatic mode
Write/disk permission failure 404 sitemap, GSC errors Alert on missing file or stale mtime
Ephemeral filesystem on redeploy Sitemap disappears after deploy Write to persistent disk/S3, regenerate on deploy
Stale sitemap after content publish New URLs never discovered Trigger on publish events or post-deploy hook
Non-canonical/parameterized URLs included Crawl budget waste, duplicate signals Filter by canonical rules; use filter() on tags
Naive lastmod values Crawler distrust of lastmod Derive from real updated_at, never now()

Ramp-up

  • API ramp-up is trivial — the README examples are copy-paste and a Laravel developer is productive within hours.
  • The actual ramp-up is SEO literacy: canonicalization, lastmod semantics, priority/changefreq (largely ignored by Google), sitemap index coverage, and GSC diagnostics. Budget roughly half a day of SEO stakeholder review of the generated output before launch, and treat that review as a gate rather than a post-launch cleanup.

Acceptance criteria for go-live

  • Sitemap and index are reachable, valid XML, and reference every child file.
  • Generated URL count is within ~5% of the expected canonical routable set, with reconciled diff against the legacy sitemap.
  • Generation runs on schedule with success/failure alerting and a documented manual re-run procedure.
  • GSC reports "Success" on the index, with discovered-URL counts trending upward over the first two crawl cycles.
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.
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo
bernskioldmedia/laravel-harvest
bernskiold/laravel-data-scrubber
bernskiold/laravel-currency-converter
bernskiold/laravel-campaign-monitor
bernskioldmedia/laravel-autotranslate
siberfx/telegram-bot
roy-sandip/laravel-view-extended
gregsphotography/site-builder-core
roy-sandip/laravel-view
anodyne/blade-fluentui-icons
webx-ui/module-catalog-collections