Skip to content

Repository files navigation

Sitemap Generate CLI

Generates the sitemaps configured in the Magento admin from the command line, and tells you where each one actually went.

Magento generates sitemaps from Magento\Sitemap\Model\Observer, a cron observer that catches every exception and reduces it to a line on an e-mail almost nobody has configured. A run that produced nothing is therefore indistinguishable from a run that worked. This command does the same generation in the foreground, lets exceptions escape with their class, message and stack trace, and afterwards verifies that the file it named really was written by this run.

composer require deployecommerce/module-sitemap-generate-cli
bin/magento module:enable DeployEcommerce_SitemapGenerateCli
bin/magento setup:upgrade

Usage

bin/magento sitemap:generate
bin/magento sitemap:generate --store-id=1
bin/magento sitemap:generate -v
Store 1: writing /var/www/html/pub/media/sitemap/sitemap.xml
  Wrote 284913 bytes, modified 2026-08-07T09:14:02+00:00.

-v additionally prints the system temp directory Magento stages each file in, the filesystem driver backing the target directory, and the number of URLs the item providers returned — an empty provider result is the other way a run looks successful and produces nothing useful.

Exit code is 0 only when every sitemap in scope was verified. Any missing or stale file makes the whole run fail, so this is safe to use as a deployment or monitoring check.

Remote storage

When remote_storage is configured in app/etc/env.php (the aws-s3 driver, for instance), the media directory is backed by a different filesystem driver. Sitemap paths are stored relative to pub, and the default path is under media/, so sitemaps are written to the remote bucket and the local pub/media/sitemap/ copy is never touched. It keeps whatever was last written there before remote storage was switched on, and its timestamp never changes again — which looks exactly like a generation that silently stopped working.

This command handles that in two ways:

  • A path under media/ is verified through the media directory, not through pub. Verifying through pub would stat the stale local leftover and report success.
  • When the target directory is not backed by the local driver, it says so and prints the local path that is not being written, so the file you are about to go and check is not mistaken for output.

The closing line changes wording too. The size and timestamp are read back through the remote driver, so what the command reports is the object existing in the bucket, not an assumption that a write was dispatched:

Store 1: writing s3://example-bucket/media/sitemap/sitemap.xml
  Remote storage is active (Magento\RemoteStorage\Driver\Adapter\CachedAdapter). The local copy at
  /var/www/html/pub/media/sitemap/sitemap.xml is not written and its timestamp will not change.
  Confirmed on remote storage (Magento\RemoteStorage\Driver\Adapter\CachedAdapter):
  s3://example-bucket/media/sitemap/sitemap.xml, 284913 bytes, modified 2026-08-07T09:14:02+00:00.

The storefront serves the remote copy through pub/get.php.

The staleness check

After generating, the command stats the file and compares its modification time against the moment generation started. A file older than that is a leftover, not this run's output, and the run fails.

Remote drivers report the modification time as a date string rather than a Unix timestamp, and their clock is not this server's clock, so there is a 60 second allowance either way. A file whose modification time cannot be read at all is accepted and reported as modified unknown — an unreadable timestamp is not evidence of a failure.

Area code

Sitemap generation reads frontend configuration, so it needs an area. The command claims crontab — the area Magento's own sitemap cron runs under — but only when nothing has claimed one already, because setting an area code twice throws.

Each sitemap is generated inside store emulation for its own store, and emulation is unwound in a finally block so a failed generation still leaves the environment clean before the exception surfaces.

Development

composer install
composer test

Tests are written with Pest and need no Magento installation. Magento's own packages are pulled from the public Mage-OS mirror, so no Adobe credentials are required. That repositories entry only applies when this package is the root package — Composer ignores it when the module is installed as a dependency.

Licence

MIT. See LICENSE.md.

About

No description, website, or topics provided.

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages