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

Php Sitemap Laravel Package

rumenx/php-sitemap

Rumenx PHP Sitemap generates standards-compliant XML sitemaps and sitemap indexes in PHP. Build URL sets, add images, videos, news, and hreflang alternates, then output plain or gzipped XML through a simple, extensible API for small sites or large dynamic applications.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What it is: A framework-agnostic XML sitemap generator with first-party Laravel and Symfony bindings. Functionally it sits at the leaf of the dependency graph — it reads URL data and emits sitemap.xml / sitemap index files. Nothing depends on it, and nothing we build should depend on it semantically.

Change since last assessment — v1.0.4 (security patch): The package shipped a fix rejecting path traversal in Sitemap::store filenames (PR #213). This materially changes the risk picture in three ways:

  1. The vulnerability is now concrete, not hypothetical. Every version ≤ 1.0.3 accepted a filename into store() without traversal rejection. That is a file-write primitive reachable from a parameter the API explicitly asks the caller to supply. For us it is only exploitable if a filename is ever derived from user-controlled input — which it should never be, but "should never be" is not a control.
  2. It is a maintenance positive signal. A single maintainer noticed, patched, and shipped a patch release. That is the behaviour we want from a bus-factor-of-one dependency. It partially offsets — but does not retire — the abandonment and dependents concerns.
  3. It weakens the "small, stable, low-churn domain" comfort argument. The sitemap protocol is stable; the code has not been hardened by a dependent ecosystem. A defect in a core write path survived to a 1.0.x line. Assume there are siblings.

Architecture fit: Unchanged and still good, if we treat it as an implementation detail rather than a platform capability. Sitemap generation is a scheduled batch job with a single output artifact. It has no runtime coupling to request handling, no schema ownership, no data mutation. That makes it trivially replaceable and low blast-radius. The framework-agnostic core is a genuine plus for us if we run mixed Laravel/Symfony/plain-PHP services, since one integration pattern covers all of them.

Integration feasibility: High on paper. Composer-installable, MIT licensed, Laravel package auto-discovery, publishable config. A competent PHP engineer should have a working sitemap in a day. The real question is not "can we install it" but "should we be the ones who find its bugs" — and v1.0.4 is evidence that bugs of the file-write class do get found here.

Technical risk — revised:

Signal Reading
1,340 stars Suggests visibility, but see below
0 dependents Still the decisive signal. Stars are cheap; dependents are earned. Zero packages depend on it, which means zero production validation we can inspect. We would be an early adopter, not a consumer.
Last release 2026-09-03 → now v1.0.4 The date anomaly on the prior release is not resolved, but the tag progression is now consistent with normal semver patch flow. Re-verify commit signatures and diff both tags against their predecessors. A security-relevant tag is exactly the tag an attacker would want to forge.
opportunity score 10.21 Low whitespace. spatie/laravel-sitemap and Symfony's equivalents already own this problem with far larger install bases. Nothing here is uniquely addressed.
Single-maintainer pattern Bus factor of one. Tolerable only behind an abstraction — and now with a documented security-patch dependency on that one person.
Path traversal in store() (fixed v1.0.4) New. Prior versions are vulnerable. Confirms the write path was insufficiently defensive. Escalates "pin your version" from hygiene to a hard requirement.

Key questions to put to the maintainer (or answer ourselves):

  • Was a GHSA/CVE issued for the traversal fix? If not, our dependency scanners and advisory feeds will not flag ≤ 1.0.3, and downstream consumers won't know to upgrade. Ask directly; a "no, it was a quiet patch" is itself a governance finding.
  • Is store() the only API that joins caller input onto a base path? Audit writeTo, index generation, and any config-driven path handling for the same class of defect. Do not assume the fix was exhaustive.
  • How was the defect found — internal review, external report, or fuzzing? The answer tells us whether there is a security process or whether this was luck.
  • Test coverage and CI matrix — which PHP versions, which Laravel/Symfony majors, is there a static analysis gate? Static analysis frequently catches exactly this traversal pattern; its presence or absence is now diagnostic.
  • Does it stream output or build a DOM in memory? This determines whether it survives a 200k-URL catalog.
  • Does it enforce the protocol limits automatically — 50,000 URLs / 50 MB uncompressed per file, and sitemap index sharding beyond that?
  • Does it support gzip output, lastmod semantics, hreflang alternates, image/video/news extensions?
  • How does it handle writes — atomic file replace, or truncate-then-write (the latter means a crashed cron leaves a corrupt sitemap live)?
  • Is robots.txt / Search Console submission in scope or left to us?
  • Why zero dependents after 1,340 stars? Ask directly; the answer is informative either way.

Verdict (revised): Technically adequate, strategically unproven, and now with one shipped security defect in its history. The patch itself is a credit to the maintainer. Approve for a bounded proof-of-concept behind an internal interface, pinned to ^1.0.4 minimum — never ≤ 1.0.3. Do not approve as a direct, unwrapped dependency in a revenue-critical service until the dependents anomaly, the release-date anomaly, and the advisory/CVE question are all answered.

Integration Approach

Stack fit: Clean. Composer + PSR-4 + Laravel auto-discovery means no build-system changes, no new runtime, no infrastructure. It slots into the existing scheduled-job tier alongside whatever already runs on cron or the queue worker.

Wrap it — non-negotiable, and more so now. Define a single internal contract, e.g. SitemapEmitter::emit(UrlSource): SitemapResult, owned by us. The package lives behind exactly one adapter class. This costs us perhaps 100 lines and buys:

  • Swap-out to spatie/laravel-sitemap or a hand-rolled streaming writer in an afternoon.
  • A stable seam for tests and for the PoC-vs-alternatives bake-off.
  • Containment if the package is abandoned.
  • New: a chokepoint where we control the filename argument, so the traversal class of bug is structurally unreachable regardless of package version.

Version constraint: "rumenx/php-sitemap": "^1.0.4" — explicitly not ^1.0, which would permit a 1.0.3 resolution from a stale lockfile or a mirror. Add a CI assertion on the resolved version.

Migration path: There is nothing to migrate from if we have no sitemap today — start with a single property, single sitemap file, no index. If we do have an existing sitemap, run the new generator in shadow mode writing to a non-public path, and diff the two outputs for a week before cutting over.

Compatibility: Confirm PHP version support against our fleet's minimum before anything else — this is the most common reason a "drop-in" package isn't. Confirm the Laravel/Symfony major we run is in the CI matrix, not merely "it worked on the maintainer's machine."

Sequencing:

  1. Due diligence (1–2 days, no code): resolve the release-date anomaly on both tags, inspect the tag diffs, confirm license and CI status, count real dependents via Packagist rather than GitHub, and establish whether an advisory/CVE exists for the v1.0.4 fix. Also sweep our estate for any existing <=1.0.3 resolution — including transitive.
  2. Spike (2–3 days): generate a sitemap for our largest known URL set. Measure peak memory and wall-clock. This is the go/no-go gate. Add a negative test: pass ../../etc/foo.xml and a null byte to store() and assert rejection. Confirm the fix holds in the version we install, rather than trusting the changelog.
  3. Adapter + tests (2 days): the internal interface, plus assertions on schema validity, URL count, and byte size. The adapter hardcodes the output filename from config — the filename is never a parameter we thread through from callers.
  4. Pilot (1 week): one low-traffic property, real Search Console submission, monitor coverage reports.
  5. Decision: promote, hold, or swap the adapter implementation. Cheap at every step.

Deliberately do not sequence SEO-critical properties first. Nothing about this package justifies front-loading risk onto our highest-value surfaces.

Operational Impact

Maintenance: Low steady-state, elevated in year one — and now measurably so. The domain is stable, but v1.0.4 demonstrates that this codebase is still shedding defects, and that the sole maintainer is the only person who will ship the next fix. Budget a nominal recurring allocation for version bumps and a standing "fork if abandoned" contingency, made cheap by the adapter. Add this package to the security-patch watchlist and subscribe to repo releases directly — if no advisory feed exists, GitHub releases are our only signal.

Support: Internal only. No vendor. The adapter author owns it; document that ownership explicitly, because unowned cron jobs are how sitemaps silently rot. Add an explicit note that security patches for this dependency route to the adapter owner, not to a general platform queue.

Scaling: The single material scaling risk is memory. A DOM-based generator will fall over on six-figure URL counts; a streaming generator won't. Confirm which this is during the spike, then set a documented ceiling and shard via sitemap index above it. Generation should run on a queue worker or dedicated cron, not in a web request.

Failure modes — ranked by business impact, which is the inverse of how loud they are:

  1. Silent SEO degradation (high impact, zero noise). The job succeeds, the file writes, the XML is malformed or truncated, crawlers drop it, rankings drift down over weeks. Nobody gets paged. Mitigation: validate against the sitemap XSD on every run, assert URL count is within an expected band, assert the public URL returns 200 with the right content type, and alert on Search Console coverage errors. Treat URL-count deltas beyond a threshold as an incident, not a curiosity.
  2. Arbitrary file write via store() filename (high impact, low likelihood given our controls). Only reachable if we ever thread untrusted input into the filename — which the adapter design forbids. Mitigation: hardcoded filename in the adapter, an assertion test for traversal inputs, and a hard floor of ^1.0.4. If the filesystem user has broad write scope, this becomes write-anywhere on the host; run the job under a constrained user regardless.
  3. Corrupt artifact from non-atomic write (high). If the generator truncates in place and the job dies mid-write, the live sitemap is garbage. Mitigation: write to a temp path and atomically rename().
  4. Cron overlap / stampede (medium). Long-running generation overlapping the next tick. Mitigation: mutex on the job.
  5. Package abandonment (medium, slow-burn). Mitigation: the adapter seam, plus a pin in composer.lock and a policy of no unattended major-version bumps — with the caveat that we now want unattended patch bumps for security, so the policy must distinguish the two.

Ramp-up: Genuinely cheap. A mid-level PHP developer is productive in half a day; the concepts (URL sets, lastmod, index files, robots.txt) are well documented and the API surface is small. The training investment is not in the package but in the monitoring — teach the on-call what a broken sitemap looks like and why it doesn't page anyone. That's the operational gap worth closing regardless of which library we pick.

Bottom line for the decision record: the package is a reasonable, low-cost implementation of a commodity problem, maintained by one person who has just demonstrated they respond to security reports. Its fitness remains unproven (zero dependents), its release metadata retains an unexplained anomaly, and it now carries a disclosed-but-unadvisored traversal fix that our scanners may not see. Approve a time-boxed spike behind an internal abstraction, pinned to ^1.0.4; withhold production approval on SEO-critical properties pending that spike, the maintainer's answers, and confirmation that no <=1.0.3 resolution exists anywhere in our estate.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager