indexnowkit/sitemap
A Laravel package for generating XML sitemaps and integrating with IndexNow to notify search engines of URL changes. It helps automate sitemap creation and keep search indexes up to date with minimal configuration.
indexnowkit/core.sitemap --new-only (0.9.0) submits only URLs that are new or changed since the last run, independent of <lastmod>. That turns a "submit everything nightly" cron into a "announce each change exactly once" capability. Decision: do you need idempotent change announcements, or is re-submitting the whole sitemap acceptable? If the latter, this release changes nothing for you.--new-only (and --changed-since) directly reduce submitted volume, which extends headroom on large catalogs and avoids burning quota on unchanged URLs. This is the input to decisions like "can we submit all 400k product URLs daily, or do we need change detection?" — and the answer now can be "change detection, cheaply."Sitemap\SeenStoreInterface with unseen(iterable<SitemapEntry>): iterable<SitemapEntry> and remember(iterable<SitemapEntry>): void, keyed on URL plus <lastmod> in ISO 8601. The package ships no store for framework adapters in this wave — the indexnow CLI keeps one in its SQLite state file; a Laravel app must implement the interface and bind it. That is an explicit build decision: a DB table, a cache-backed store, or a Redis set, plus a retention/pruning policy for stale fingerprints.--new-only runs is the intended operating pattern. That is a two-job design (bootstrap + incremental), and it interacts with publishing workflows: when do new/changed URLs become visible to the sitemap, and how soon after publish should submission fire? --changed-since and --new-only compose (time window first, then the store), so windowing and change detection can be layered rather than chosen between.remember() is called only for batches whose results did not fail, and never on --dry-run. This means failed submissions are retried on the next run rather than silently marked as announced — a correctness property worth relying on before you build your own.--new-only and no store bound, the runner returns SitemapRunner::NO_SEEN_STORE (exit 2) and reads nothing. In a Laravel context this is a deploy-time failure, not a data-corruption failure; it argues for a health check or a test asserting the binding exists.Consider it when:
Console\Definitions::sitemap() option declaration is wired for every adapter, so configuration stays uniform across the CLI and framework entry points.--new-only is the reason to adopt this version rather than an earlier one., N new or changed summary line and the "announce each change once" behaviour give you something to log and alert on.SeenStoreInterface implementation. If that is a table you already have (or a cache you already run), the marginal cost is low.Look elsewhere or wait when:
--new-only is your whole motivation and you cannot implement the interface, you get exit 2, not a feature.indexnowkit/core ^0.13.1; interface signatures and option names can still move. Treat the store contract as a coupling point you may have to migrate.--new-only fingerprints URL plus <lastmod>; if <lastmod> is absent or wrong, the fingerprint still works for URL additions but changed-content detection degrades to URL identity. --changed-since depends on <lastmod> more directly.For executives: Search engines only crawl what they are told about, and IndexNow is the fast path for Bing, Yandex, Seznam, and Naver. This package automates that submission from the sitemap we already publish, and the 0.9.0 release makes it incremental: instead of re-announcing every URL every night and consuming our per-host quota, it announces each new or changed URL once and stays quiet about the rest. That is the difference between a nightly job that mostly wastes quota and one whose volume tracks actual publishing. It is a pre-1.0 package (0.9.0, pinned to indexnowkit/core ^0.13.1), so budget a small integration cost and expect the interface to move before 1.0.
For engineering: Adoption is a scheduled command plus one class. The command reads the sitemap, filters hosts, batches submissions, and prints a summary that now includes , N new or changed. --new-only is implemented against Sitemap\SeenStoreInterface — unseen() is called once after the host filter, remember() once per successful batch, never under --dry-run — with fingerprints of URL plus ISO 8601 <lastmod> (or empty). The Laravel adapter does not ship a store, so --new-only without a binding answers SitemapRunner::NO_SEEN_STORE and exits 2 before reading anything: plan for a database or cache-backed store, a pruning job for stale entries, and a test that asserts the container binding. Failed batches are deliberately not remembered, so retry is the default — do not build your own retry marking around it. --changed-since and --new-only compose (window first, then store), so a backfill run plus a tighter scheduled run is a supported shape. Budget for the upgrade surface: pre-1.0, and the core ^0.13.1 floor is not optional.
For product: The operating model to design around is a slow full run that seeds the store, then frequent --new-only runs after publishing. That is the decision that matters — how quickly after a publish a URL should be announced, and what happens when a publish event and the sitemap disagree. The package is the transport, not the trigger; you still own the scheduling and the question of when a change becomes "seen."
How can I help you explore Laravel packages today?