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.
Architecture fit. Sitemap generation is a read-side, derived-data concern — it should never participate in domain logic. Release 1.12.0 stays inside that boundary: it maps a model's existing created_at/updated_at attributes onto the <lastmod> element of emitted sitemap entries. There are no schema changes, no new persistence layer, no events or observers, and no change to how URLs are discovered. From an architecture standpoint this is a formatting/enrichment change to an output artifact, which is the lowest-risk category of change a package in this position can ship.
Integration feasibility. The change is almost certainly config-gated or opt-in per sitemap definition, consistent with how this package class typically handles optional <lastmod> emission. Integration effort is bounded by: confirming the published config exposes the new behavior, confirming the model selection mechanism (explicit model list vs. query-based) propagates timestamps, and confirming output format. No new transitive dependencies, no service provider changes required beyond a composer update. A developer familiar with Laravel should be able to validate this end-to-end in under a day.
Technical risk. The risk is not in the code path; it is in semantic correctness of the data being published. Three concerns dominate:
<lastmod> must be W3C datetime. Application timezones that are not UTC, or Carbon instances rendered without explicit toW3n-style normalization, will produce technically valid but inconsistent values. This is the single most likely defect.updated_at is not a content-change signal. Many teams bump updated_at on counter increments, touch() calls from related models, admin toggles, or queue-driven denormalization. Publishing those as <lastmod> trains search engines to distrust the field — Google explicitly ignores lastmod when it is found to be unreliable. This is a reputational risk with the crawler, and it is a product decision, not a package defect.$timestamps = false, soft-deleted records, or hand-constructed entries may yield null timestamps. Need to confirm the package omits <lastmod> rather than emitting an empty or epoch value.Minor and worth noting: exposing precise edit cadence for every URL is a small information-disclosure surface for internal-content sites.
Key questions.
updated_at is null — omit, or use created_at?config('app.timezone')?Stack fit. Standard Laravel footprint: PHP 8.x, a Laravel version within the package's supported matrix, the framework scheduler for regeneration, and a filesystem disk (local or S3) for artifact storage. Nothing here changes that shape. The package remains a scheduled batch job producing a static artifact — no runtime request-path involvement, no queue workers strictly required unless the deployment already generates asynchronously.
Migration path. This is a minor version bump (1.x → 1.12.0) and the change is additive; semver permits treating it as non-breaking. Practical path:
composer update to 1.12.0 in a branch.config/sitemap.php against the package's current stub. This is the most common failure point in Laravel package upgrades — if the config was published on an earlier version, new keys will not appear and the feature will appear silently inert or, worse, fall back to a default that differs from intent.<lastmod> presence, format, and timezone.xmllint --schema) as a CI step, not a manual one.Compatibility. Backward compatible for consumers who have not published or have not customized the config. Teams that subclassed the generator or overrode entry-rendering methods should verify their overrides still receive the timestamp payload. Teams pinning a fork of the package will need to rebase.
Sequencing. Ship in this order: (a) merge config + regenerate in a non-production environment; (b) add XML schema validation to CI so future upgrades cannot silently emit malformed lastmod; (c) deploy to production with a single regeneration and confirm via Search Console / Bing Webmaster Tools that the sitemap is re-fetched without parse errors; (d) only then decide whether to enable the feature broadly or restrict it to content collections where updated_at is a genuine editorial signal. Steps (c) and (d) should be separate releases — the ability to emit lastmod and the decision to emit it everywhere are different risk decisions.
Maintenance. Negligible ongoing cost. The change has no runtime dependencies, no background processes, and no state to reconcile. The maintenance obligation is the usual one: track upstream minor releases and re-validate the XML schema on each bump.
Support. Expected to reduce a class of tickets ("why is the sitemap not showing update dates?") while introducing a narrower one ("why is the date wrong / off by hours / showing today for every URL"). The second category is diagnosable with a single query against the source table, so mean time to resolution should be short. Document the timezone assumption in the team runbook — that one line prevents most escalations.
Scaling. Effectively neutral. Each entry gains roughly 20–30 bytes of XML; at the 50,000-URL-per-file ceiling this is ~1.5 MB of additional artifact size, immaterial against typical transfer limits. Generation time is unchanged because the timestamps are already loaded on the model instances. No impact on crawl budget from the artifact itself.
Failure modes. Ranked by likelihood × impact:
| Mode | Likelihood | Impact | Detection |
|---|---|---|---|
| Non-UTC timestamps emitted | Medium | Medium — crawler misinterprets freshness | Inspect generated XML; schema validation won't catch it |
updated_at bumped by non-content writes |
High | High — lastmod becomes untrustworthy and is discounted |
Compare lastmod distribution; audit touch() usage |
Null timestamps emitting empty <lastmod> |
Low–Medium | Medium — parse errors in Search Console | Schema validation in CI |
| Published config missing new keys | Medium | Low — feature silently inert | Post-deploy XML inspection |
| Sitemap cache not invalidated after deploy | Low | Low — stale artifact served briefly | Regeneration on deploy hook |
The updated_at-semantics row is the one that deserves a written decision. It is the only failure mode here that cannot be fixed by a config flag or a code patch; it requires either accepting the noise or restricting the feature to models with disciplined update semantics.
Ramp-up. Low. A mid-level Laravel developer can integrate, validate, and document this in half a day, most of which is spent on the config-diff and XML inspection steps rather than the package itself. The TPM-facing learning curve is not technical but editorial: understanding what lastmod signals to crawlers and when publishing it helps versus hurts. Budget a short briefing for whoever owns SEO/analytics so the rollout decision is made with that context rather than by default.
How can I help you explore Laravel packages today?