Skip to content

Remote Thumbnail Generation

Remote Thumbnail Generation

INFO

This feature is available starting with Shopware version 6.6.4.0. The {mediaUpdatedAt} pattern variable was added in 6.6.5.0, and the ResolveRemoteThumbnailUrlExtension hook was added in 6.7.1.0.

In certain scenarios, you might want to disable the filesystem thumbnail generation in Shopware and use an external CDN service to handle the thumbnails. This can be beneficial for performance and scalability reasons. When the remote thumbnail configuration is enabled, the thumbnail images and thumbnail records in the database are not generated by Shopware, but by the external service.

Configuration

To use remote thumbnails, you need to adjust the following parameters in your config/packages/shopware.yaml:

yaml
shopware:
  media:
    remote_thumbnails:
      enable: true
      pattern: '{mediaUrl}/{mediaPath}?width={width}&ts={mediaUpdatedAt}'
KeyTypeDefaultDescription
shopware.media.remote_thumbnails.enableboolfalseMaster switch. When true, Shopware stops creating, persisting, and deleting thumbnail files and database records and instead synthesizes thumbnail URLs from the configured pattern at request time.
shopware.media.remote_thumbnails.patternstring{mediaUrl}/{mediaPath}?width={width}&ts={mediaUpdatedAt}Template used to build thumbnail URLs. Variables are listed below.

The pattern supports the following variables:

  • mediaUrl: The base URL of the public filesystem (shopware.filesystem.public). For media whose path is already absolute (e.g., uploaded by URL), {mediaUrl} is replaced with an empty string and the leading slash is trimmed automatically.
  • mediaPath: The media file path relative to mediaUrl (for example media/ab/cd/file.jpg).
  • width: The width from the assigned media_thumbnail_size of the media folder.
  • height: The height from the assigned media_thumbnail_size of the media folder.
  • mediaUpdatedAt: Unix timestamp of media.updatedAt, falling back to media.createdAt. Empty string when both are null. Useful as a cache-buster (Shopware versions older than 6.6.5.0 do not support this variable).

For example, with the default pattern {mediaUrl}/{mediaPath}?width={width}&ts={mediaUpdatedAt}, the thumbnail URL is generated as https://yourshop.example/abc/123/456.jpg?width=80&ts=1718954838.

WARNING

Private media is intentionally excluded from remote URL generation: it keeps using its signed local URL even while the feature is enabled. Plan accordingly if your shop relies on private media.

Usage

Once the configuration is set, Shopware will automatically use the defined pattern to generate thumbnail URLs. These URLs will point to the external CDN service, which should handle generating and delivering the thumbnail images.

Please note that the external service needs to be able to handle the URL pattern and generate the appropriate thumbnails based on the provided parameters.

Behavior when enabled

Enabling shopware.media.remote_thumbnails.enable short-circuits multiple subsystems. Plugins that interact with thumbnails directly should be aware of the changes:

  • ThumbnailServicegenerate(), updateThumbnails(), and deleteThumbnails() throw MediaException::thumbnailGenerationDisabled() (HTTP 400, error code MEDIA_THUMBNAIL_GENERATION_DISABLED). Guard custom code that calls these methods.
  • Message handlerGenerateThumbnailsHandler and UpdateThumbnailsHandler consume but no longer process GenerateThumbnailsMessage / UpdateThumbnailsMessage.
  • Media indexerMediaIndexer::iterate, update, and handle early-return, so no MediaIndexingMessage is enqueued and media.thumbnails_ro is not maintained (since 6.7.1.0). Running bin/console dal:refresh:index media.indexer is a no-op.
  • CLI commandsbin/console media:generate-thumbnails aborts with Command::FAILURE and prints Remote thumbnails are enabled. Skipping thumbnail generation.
  • FileSaver — uploads no longer dispatch a GenerateThumbnailsMessage, and renames skip the thumbnail-rename step (which would otherwise fail because no local thumbnail files exist).
  • MediaDeletionSubscriber — original files are still deleted, but the thumbnail-file enumeration and the media_thumbnail row deletion are skipped.
  • MediaUrlLoader — listens to media.loaded / media.partial_loaded and delegates to RemoteThumbnailLoader, which synthesizes a MediaThumbnailCollection in memory based on the media folder's configured media_thumbnail_size entries.

WARNING

The synthesized MediaThumbnailEntity instances are assigned a fresh random UUID on every request and are not persisted. Do not rely on media_thumbnail.id being stable, and do not join other tables against it while the feature is on.

Cleaning up local thumbnails

If you switch from local to remote thumbnails on an existing shop, the previously generated media_thumbnail records and files remain in storage. Shopware ships a CLI command (added in 6.6.6.0) that removes them:

bash
bin/console media:delete-local-thumbnails

The command only runs when remote thumbnails are enabled. It deletes every row from media_thumbnail, removes the corresponding files via the configured filesystem adapter, and clears the serialized media.thumbnails_ro column so that the storefront immediately stops referencing stale entries.

Extending the URL generation

RemoteThumbnailLoader dispatches the URL through the ResolveRemoteThumbnailUrlExtension (extension name remote_thumbnail_url.resolve, available since 6.7.1.0). Apps and plugins can subscribe to it to:

  • rewrite the URL (for example, sign it, route it through an image-resizing proxy, swap the host per sales-channel),
  • return null to skip a thumbnail entirely (since 6.7.3.0),
  • read the full MediaEntity to make decisions based on mimeType, custom fields, or folder configuration.

Subscribe to the extension via the standard extension event mechanism. Do not modify MediaUrlLoader or RemoteThumbnailLoader directly; both are marked @final and may change.

Invalidating Thumbnails with Fastly

If you are using Fastly as your CDN, you can let Shopware invalidate the cached thumbnails when media is updated. To do this, configure your Fastly API key in your config/packages/shopware.yaml:

yaml
shopware:
  cdn:
    fastly:
      api_key: '%env(FASTLY_API_KEY)%'
      soft_purge: false
      max_parallel_invalidations: 2
KeyTypeDefaultDescription
shopware.cdn.fastly.api_keystring''Personal Fastly token. Setting this to a non-empty value is what activates media invalidation — there is no separate enabled flag. With an empty key, the listener silently no-ops.
shopware.cdn.fastly.soft_purgebool/stringfalseSent verbatim as the fastly-soft-purge request header. Set to true (or '1') to keep serving stale content while purges propagate.
shopware.cdn.fastly.max_parallel_invalidationsint2Guzzle pool concurrency for purge requests. Bounds how many POST https://api.fastly.com/purge/{url} calls are in flight simultaneously.

When media changes (path change, file update, or deletion), the BanMediaUrl listener resolves all affected URLs and dispatches them through FastlyMediaReverseProxy, which sends one purge request per URL. Failures are logged at critical level and do not block the write process.

INFO

This is the media-cache Fastly configuration node. It is independent from shopware.http_cache.reverse_proxy.fastly, which configures the storefront's HTTP-cache invalidation gateway and exposes additional options such as service_id, instance_tag, and tag_prefix. See Reverse HTTP cache for the storefront side.

Conclusion

By using remote thumbnails, you can offload the task of thumbnail generation to an external service, potentially improving the performance and scalability of your Shopware installation.

Was this page helpful?
UnsatisfiedSatisfied
Be the first to vote!
0.0 / 5  (0 votes)