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

Sitemap Laravel Package

samdark/sitemap

A lightweight sitemap generator for Yii2 applications. Build XML sitemaps and sitemap indexes, add URLs with last-modified, change-frequency, and priority metadata, and write or cache the output. Supports gzip compression and straightforward integration with Yii2 projects.

Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • samdark/sitemap is a narrow, single-responsibility library: it builds sitemap XML (<urlset>) and sitemap index XML (<sitemapindex>) documents from in-memory collections of URL entries. It is not a Laravel package — there is no service provider, no facade, no publishable config, and no Eloquent/queue/filesystem awareness. That is a deliberate design choice by the author (Alexander Makarov, a Yii core maintainer) and it means the library drops into a Laravel app as a plain Composer dependency behind our own integration layer.
  • Fit is strongest where we want full control over sitemap composition (multi-tenant, multi-locale, curated URL sets) and weakest where we want turnkey behavior (auto-discovery of routes, model observers, scheduled regeneration). We will be writing the Laravel-shaped 30% ourselves.
  • Because it only emits XML, it composes cleanly with Laravel's Storage facade for writing to local/S3 disks and with Response/streamed responses for serving. There is no impedance mismatch with our request lifecycle.
  • The absence of framework coupling is also the main architectural gap: URL discovery, chunking, and index assembly are entirely our problem, and they are where the real engineering effort sits.

Integration feasibility

  • High. composer require samdark/sitemap plus a thin adapter service is a one-day spike. The public surface is small (generator, index generator, sitemap/URL value objects), which means a low-cost wrapper and a low blast radius if we ever swap it out.
  • The realistic work is upstream of the library: enumerating canonical URLs from Eloquent models, enforcing per-entry metadata (lastmod, changefreq, priority, and, if needed, hreflang alternates), splitting into ≤50,000-URL / ≤50MB chunks, and emitting a matching index. Budget 3–5 engineer-days for a production-grade implementation including tests, not the 1 day the Composer install implies.
  • Serving is straightforward: an Artisan command writes files to storage/app/public/sitemaps/, a route or static file serves /sitemap.xml, and robots.txt references the index. No middleware or runtime dependency on the library in the hot path.

Technical risk

  • Maintainer concentration (medium): 543 stars and a BSD-3 license indicate healthy adoption, but the project is effectively single-maintainer. The unknown/absent repository URL in our metadata is a governance flag — we must confirm the canonical repo and pin a version before adoption.
  • Low velocity risk (low): a sitemap builder is a near-frozen problem domain; the last release (2026-07-20) suggests the project is current. Feature stagnation is acceptable here because the protocol is stable.
  • Feature-coverage risk (medium): we need to verify support for sitemap index generation limits, lastmod formatting (W3C datetime), XML escaping of query strings and non-ASCII URLs, and whether image/video/news extensions or gzip output are in scope. Anything missing becomes our code, and gzip in particular is usually a wrapper concern rather than a library concern.
  • Scale/memory risk (medium): the API is collection-oriented — it renders a document from an in-memory set of entries. At 50k URLs with long query strings we approach memory limits. We must paginate at the database layer via chunkById and never Model::all().
  • Unscored metadata risk (low): the composite score of ~20.7 is likely depressed by the missing repository URL rather than by code quality. Treat the score as a prompt to verify provenance, not as a verdict on fitness.

Key questions

  1. Which PHP versions and XML extensions (ext-dom vs ext-xmlwriter) does the current release require, and does that match our fleet's baseline?
  2. Does it natively support sitemap index generation with correct child-sitemap references, or must we hand-assemble the index?
  3. How are URL escaping and non-ASCII/IDN paths handled — does it XML-escape ampersands and encoded characters correctly?
  4. Is there first-class support for lastmod formatting, hreflang xhtml:link alternates, and image/video/news extensions, or is that on us?
  5. What is the canonical repository and release cadence, and is there a documented security-response channel?
  6. Does it impose any per-document entry limits or validation, or is it purely a serializer?

Integration Approach

Stack fit

  • Laravel 10/11 on PHP 8.2+, MySQL/Postgres, Redis, S3 or local disk. The library imposes no constraints on any of these; it needs only a PHP XML extension and will run anywhere the app runs.
  • Recommended shape: a SitemapBuilder service in app/Support/Sitemap that wraps SitemapGenerator/SitemapIndexGenerator, a set of SitemapSource implementations (one per content type: products, categories, CMS pages, blog posts), and an Artisan command sitemap:generate that orchestrates sources → chunks → files → index.
  • Writing goes through Storage::disk('public')->put(...) or a dedicated sitemaps disk, so local dev and S3 prod behave identically. Serving is a static file behind the CDN — zero PHP in the request path.
  • Keep the library behind our interface (SitemapWriter), with a single adapter class as the only file importing samdark\sitemap\*. If we later migrate to spatie/laravel-sitemap or a homegrown XMLWriter, the swap is one class.

Migration path

  • From nothing: ship the command plus a scheduled job, register /sitemap.xml in routes or as a static file, and add the Sitemap: directive to robots.txt. Two PRs.
  • From spatie/laravel-sitemap: run both generators in parallel for a release, diff the output URL sets, then cut over and remove the old package. The migration is mostly about reproducing crawl-frequency and priority heuristics, which Spatie exposes via model methods and we would express as source-level policy.
  • From hand-rolled XML: the wrapper centralizes escaping and formatting, which typically fixes latent bugs (unescaped &, naive string concatenation) as a side effect.
  • Data migration: none. Sitemaps are derived artifacts; the only state is the generated files, which are disposable and idempotently rebuilt.

Compatibility

  • No conflict risk: it declares no Laravel or Symfony dependencies and does not monkey-patch framework internals, so Composer resolution is safe alongside our existing packages.
  • Watch the PHP/extension floor and the ext-* requirement in CI — our container image must include the XML extension explicitly rather than relying on a dev machine's defaults.
  • Behavior is deterministic given the same input ordering; that matters for diffing and for CDN cache-stability. Sort entries by a stable key before rendering.

Sequencing

  1. Week 1 — spike (1–2 days): verify feature coverage against the key questions; confirm the canonical repo and pin an exact version in composer.json.
  2. Week 1 — adapter: build SitemapWriter + SitemapBuilder with unit tests covering escaping, lastmod format, and index chunk boundaries at 49,999/50,000/50,001 entries.
  3. Week 2 — sources: implement 2–3 SitemapSource classes using chunkById, starting with the highest-value content type; add a per-source URL cap and log truncation.
  4. Week 2 — delivery: Artisan command, scheduler entry (nightly, off-peak), disk config, route/static serving, robots.txt update, and a smoke test asserting well-formed XML and a reachable index.
  5. Week 3 — rollout: run in shadow mode comparing against any incumbent output, submit to Search Console, monitor crawl stats, then decommission the old path.
  6. Deferred: gzip output, hreflang alternates, image/video extensions — treat as follow-ups gated on SEO requirements rather than blocking v1.

Operational Impact

Maintenance

  • Low steady-state burden: the library is a serializer with a stable protocol, so version bumps should be rare and low-risk. Our own wrapper and source classes carry the real maintenance load.
  • Ownership should sit with the platform/backend team. The single-maintainer profile means we should track upstream releases via Renovate/Dependabot and be prepared to vendor or fork; BSD-3 permits that without friction, which materially de-risks abandonment.
  • Documentation burden is modest but real: the source-registration pattern and the "add a new sitemap source" runbook are the things a future engineer will need.

Support

  • No vendor, no SLA — community-only via GitHub issues. Acceptable for a non-critical, derived-output component.
  • Incidental support load comes from content teams asking "why isn't my page in the sitemap": build a sitemap:inspect --url= diagnostic early to answer that without engineering time.
  • Search Console is the de facto monitoring surface; assign a named owner for crawl-error triage.

Scaling

  • URL volume scales linearly and is bounded per-file by the 50k/50MB protocol limits, so growth is handled by adding index children, not by changing architecture. At ~1M URLs expect ~20+ child sitemaps and a few minutes of generation time — well within a nightly window.
  • Generation is CPU- and memory-light per chunk but should run as a queued job on a dedicated worker to keep it off web nodes and out of the request pool. Chunked DB reads (chunkById) are mandatory; with them, peak memory stays flat regardless of corpus size.
  • Serving scales trivially because files are static and CDN-cacheable. Set sensible Cache-Control on the sitemap route and invalidate on regeneration, or content changes will lag crawl discovery by a full cache TTL.
  • Multi-tenant/multi-locale deployments multiply the file count; shard by tenant/locale prefix and reference each shard from a per-tenant index.

Failure modes

  • Memory exhaustion on unbounded queries — highest-probability failure; enforce chunking and add a hard per-source URL cap with a warning log.
  • Stale sitemap — the scheduler silently stops, or generation fails and the previous file persists. Add a freshness check: assert the index lastmod is within 48 hours and alert otherwise.
  • Malformed XML from unescaped input — a single & or invalid UTF-8 byte corrupts the document and Google rejects the whole file. Mitigate with a post-generation well-formedness validation step and sanitization at the source layer.
  • Silent truncation at the 50k/50MB boundary — URLs beyond the limit are dropped without error unless we explicitly detect and roll to the next chunk. Test the boundary.
  • Disk/permission failure — writes to a misconfigured disk or a full volume produce a zero-byte or partial file. Write to a temp path and atomically rename.
  • Index/child drift — child files exist but the index doesn't reference them (or vice versa) after a partial run. Generate to a staging directory and swap atomically.
  • Deploy-window races — a mid-deploy regeneration can produce a half-written set; serialize generation with withoutOverlapping() on the scheduled job.

Ramp-up

  • A mid-level Laravel engineer can be productive in half a day: the library API is small and the wrapper is deliberately thin.
  • The learning curve is not the library — it's the SEO domain rules (canonicalization, lastmod honesty, priority/changefreq semantics, hreflang) and our source-registration convention. Budget a short written standard for what qualifies for inclusion.
  • First-week checklist: confirm PHP extension baseline in CI, pin the version, validate the 50k boundary test, wire the freshness alert, and document the "add a source" runbook. After that, the component runs unattended.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
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