Skip to content

Release notes Shopware 6.7.12.0

6.7.2026

Release notes Shopware 6.7.12.0

Do not install

This release cannot be installed or updated to because it contains a breaking issue discovered shortly after release. Please use v6.7.12.1 instead.

We kept the regular release cycle to avoid disrupting continuous integration and versioning for our community. The changes from this version are still listed below, but they are only available by installing v6.7.12.1, which includes a fix for the issue.

Abstract

Shopware 6.7.12.0 closes 332 issues, focusing heavily on operational stability and AI readiness. It improves checkout fallbacks, order handling, product feeds, media uploads, customer data, Administration usability, accessibility, caching, Elasticsearch/OpenSearch behavior, and migration reliability. The release also expands platform capabilities with agent-facing sales-channel files, MCP endpoints, improved webhooks, enhanced rule builder features, richer product comparison data, and standardized CLI output options.

System requirements

  • tested on PHP 8.2, 8.4 and 8.5
  • tested on MySQL 8 and MariaDB 11

Improvements

Features

Agentic files for sales channels

Sales channels can now publish opt-in agentic files such as /llms.txt and /agents.md. Merchants can manage these files in the sales channel details, enable them per sales channel, preview the generated content, and add custom notes without replacing the default content provided by Shopware or extensions.

Core ships the initial agentic file family. The files are rendered from Twig templates, so Shopware, plugins, apps, and themes can contribute or extend content through normal Shopware Twig inheritance. Extensions can add additional templates under Resources/views/files/agentic/**.twig, including nested paths such as .well-known/*.

The Admin API exposes documented action routes for listing, reading details, and previewing sales-channel files under /api/_action/sales-channel-file/{fileFamily}/{salesChannelId}.

Storefront

Storefront cache hash no longer varies by language

The HTTP cache hash no longer includes the language id for storefront requests, because the storefront language is derived from the resolved domain URL. Store API requests still include the language id in the cache hash, as the same Store API URL can return different languages via the sw-language-id header.

Central extension point for content before/after list prices

A new template @Storefront/storefront/component/product/list-price-affix.html.twig is rendered inside every list price display (product box, product detail buy widget, advanced pricing table). It replaces the deprecated listing.beforeListPrice / listing.afterListPrice snippets as the single place to inject content around list prices.

Content can be provided in two ways:

  • Without code: create a translation snippet with a custom key and enter that key in the new sales-channel-aware system config settings core.listing.beforeListPriceSnippetKey / core.listing.afterListPriceSnippetKey. The snippet content is rendered sanitized, wrapped in a list-price-affix list-price-affix-{before|after} span.
  • In a theme or plugin: override the block component_list_price_affix_content once; the position variable (before / after) allows position-specific output.

Thumbnail sizes attribute now emits a value for the XXL breakpoint

The auto-generated sizes attribute produced by thumbnail.html.twig now includes a value for the XXL breakpoint. The xxl key is the open-ended top (container / columns), and xl is a closed range bounded by breakpoint.xxl - 1, matching the pattern used by smaller breakpoints. Templates that pass a manual sizes map to sw_thumbnails should add an xxl entry to keep parity.

Use Bootstrap variable for headings spacing

The hard-coded CSS margin-bottom was removed from HTML headlines H1-H6. The bootstrap variable $headings-margin-bottom can now be used to set the bottom spacing of headlines.

Storefront XHR login failures now keep HTTP 403

Storefront requests that require a logged-in customer no longer redirect to the login page for XMLHttpRequests when the customer session is no longer valid. The original 403 Forbidden response is preserved. Regular page requests still redirect to the login page. This prevents expired sessions from creating redirect chains from XHR endpoints to page controllers and fixes the follow-up failure where the redirected XHR request reaches the login page, which does not allow XHR access. JavaScript clients can now handle the failed unauthenticated XHR response explicitly.

Mail templates can access storefront theme configuration

Mail templates rendered for a sales channel now receive a temporary salesChannelContext and the assigned themeId. This allows Twig helpers such as theme_config() to resolve storefront theme configuration in mails without replacing the existing core context variable. The shared MailTemplateRenderContextEvent is dispatched for both sent mails and preview/simulation rendering so extensions can enrich mail template data through one hook.

A new Enhanced Conversions option was added to the Google Analytics integration. When enabled in the sales channel analytics settings, the checkout finish page sends the SHA256-hashed customer email address via gtag('set', 'user_data', ...) to support Google Ads Enhanced Conversions. Email addresses are normalized according to Google's requirements before hashing.

A new enhanced_conversions boolean field was added to SalesChannelAnalyticsDefinition and SalesChannelAnalyticsEntity.

New extensible Twig block page_checkout_finish_enhanced_conversions has been added to finish-details.html.twig.

Country state field visibility in address forms

Storefront address forms now respect the country displayStateInRegistration setting. When disabled, the country state field is hidden unless forceStateInRegistration is enabled, in which case the required state field is still shown. During the update, displayStateInRegistration is activated for every country that has at least one configured state/region. This keeps existing storefront address forms showing their state selector until the setting is disabled explicitly.

Checkout gateway blocked method fallback

Storefront checkout cart and confirm page loading now resolves payment and shipping methods blocked by the checkout gateway before rendering the page. The fallback method is selected from the checkout gateway response, preferring the sales-channel default method when available and otherwise using the first available method declared by the gateway.

Customer address fields are trimmed on new writes

Customer address fields submitted through storefront registration and address updates are now trimmed before they are written. This prevents leading or trailing whitespace from being stored in standard address fields such as first name, last name, street, city, and zipcode.

Existing customer address records are not changed.

New contentSelector option for the AlertAriaPlugin

The AlertAriaPlugin now supports a contentSelector option to define the content element inside the aria-live region that is toggled to trigger the screenreader. It defaults to .alert-content-container. Override it when applying the plugin to custom markup that is not based on the alert template:

twig
<div class="cart-live-update visually-hidden"
     role="status"
     aria-live="polite"
     data-alert-aria="true"
     data-alert-aria-options='{{ { contentSelector: ".cart-live-update-content" }|json_encode }}'>
    <div class="cart-live-update-content">
        {# ... content that should be announced ... #}
    </div>
</div>

API

Plain JSON API includes preserve extension wrappers

The Admin API plain JSON encoder now keeps extension association fields inside the extensions object when they are selected through includes. For example, including an extension association such as toOne on an entity returns extensions.toOne instead of promoting toOne to the top-level response. Nested extension entities also respect their own include definitions, so API clients can filter extension payload fields consistently.

Customer email uniqueness is enforced on writes

Admin API and Sync API customer writes now enforce the same non-guest customer email uniqueness rules as the Administration customer form and Store API registration flows. When core.systemWideLoginRegistration.isCustomerBoundToSalesChannel is disabled, a non-guest customer email must be unique globally. When the setting is enabled, duplicate non-guest emails are only accepted for customers bound to different sales channels. Extensions can use Shopware\Core\Checkout\Customer\Validation\CustomerEmailUniqueChecker with CustomerEmailUniqueCheck to apply the same configuration-aware uniqueness rules.

Number range previews can target a concrete number range

The Admin API now supports previewing a persisted number range by id via /api/_action/number-range/{numberRangeId}/preview-pattern. Use this route when editing an existing number range, because it reads the state for the concrete number_range.id.

The previous type-based preview route /api/_action/number-range/preview-pattern/{type} remains available in 6.7 for backwards compatibility, but is deprecated and will be removed in 6.8. It can only resolve global number ranges and therefore does not support non-global number range state. The allocation route /api/_action/number-range/reserve/{type} is unchanged.

Empty sw-* id headers are treated as unset

Admin API and Store API requests now treat empty ID headers such as sw-language-id, sw-currency-id, sw-app-integration-id, and sw-app-user-id the same as missing headers. Empty values fall back to the default request context instead of being forwarded as invalid UUIDs. Whitespace-only values are still rejected as malformed IDs.

For cache efficiency, clients should consistently either omit sw-language-id and sw-currency-id or send them empty when they intentionally want default context resolution, because these headers can participate in reverse-proxy cache keys.

Administration users receive default runtime privileges

Authenticated Administration users now receive the default privileges required by global Admin helpers: language:read, locale:read, message_queue_stats:read, log_entry:create, currency:read, and country:read. The Administration role editor also adds these privileges to newly generated role permission sets.

Core

Rule Builder: new "Quantity per item" condition

A new line item rule condition LineItemPerItemQuantityRule (cartLineItemPerItemQuantity) was added. It matches the cart against the quantity of each individual line item, without selecting a specific product.

Storefront snippets of self-managed apps are loaded

Storefront snippet files (Resources/snippet/*.json) shipped by self-managed apps (services) are now loaded. Previously, the snippet loader resolved app snippets only from the local app directory, which self-managed apps do not have, so their storefront snippets were silently ignored. The snippet files are now resolved through the app source system, the same way assets, scripts, and admin snippets of self-managed apps already are. Service developers no longer need to work around missing storefront translations; the same app zip now behaves identically whether installed as a regular app or as a service.

Deprecation of shopware.cache.cache_compression and shopware.cache.cache_compression_method config options

The shopware.cache.cache_compression and shopware.cache.cache_compression_method configuration options are deprecated and will be removed in v6.8.0.0. Please use the new shopware.cache.compress and shopware.cache.compression_method options instead.

Before
yaml
shopware:
    cache:
        cache_compression: true
        cache_compression_method: 'gzip'
After
yaml
shopware:
    cache:
        compress: true
        compression_method: 'gzip'

Stored mail template type data deprecated

The persisted mail_template_type.template_data column is deprecated and will be removed in Shopware 6.8. It was only used as stored preview data and is no longer needed after the mail template preview refactoring.

Use explicit templateData in the mail preview and send APIs, or generated data from the simulate endpoint, instead. The mail API request payloads templateData and mailTemplateData remain supported and are not part of this deprecation.

Pluggable thumbnail image processor

The thumbnail generation pipeline now uses a ThumbnailProcessorInterface instead of a hardwired GD implementation. Two processors ship out of the box:

  • GdImageThumbnailProcessor — uses the PHP GD extension and is the default.
  • ImagickThumbnailProcessor — uses the PHP Imagick extension, if installed.

Switch between them in config/packages/shopware.yaml:

shopware:
  media:
    thumbnail_processor: imagick   # or "gd" (default)

Both processors work with the new ThumbnailImage DTO (Shopware\Core\Content\Media\Thumbnail\DTO\ThumbnailImage), which is a thin wrapper carrying the underlying image resource. ThumbnailService only ever deals with ThumbnailImage objects and is fully agnostic of the concrete library.

Core Twig config() helper

The Twig config() helper is now provided by the core Twig environment so non-storefront templates can read sales-channel-aware system configuration. Twig templates can continue using config('my.config.key') unchanged.

The PHP methods Shopware\Storefront\Framework\Twig\Extension\ConfigExtension::config() and Shopware\Storefront\Framework\Twig\TemplateConfigAccessor::config() are deprecated. PHP code should use SystemConfigService directly instead.

Number range value generator interface deprecated

NumberRangeValueGeneratorInterface is deprecated in favor of AbstractNumberRangeValueGenerator. Custom number range value generator implementations and decorators should extend the abstract class instead. Implement previewPatternByNumberRangeId() for persisted number-range previews and continue using getValue() for actual number allocation.

The type-based previewPattern() method remains available for backwards compatibility in 6.7, but is deprecated and will be removed in 6.8. Use previewPatternByNumberRangeId() when previewing or editing an existing number range.

Orders no longer break on missing rule conditions in price definitions

If an order's AbsolutePriceDefinition, CurrencyPriceDefinition, or PercentagePriceDefinition references a rule condition that is no longer registered (e.g. a plugin contributing it has been uninstalled), PriceDefinitionFieldSerializer no longer throws ConditionTypeNotFound/InvalidConditionException. Such conditions are substituted with a new internal UnknownConditionRule whose match() always returns false.

The original rule payload is preserved verbatim on reads, order versioning and normal saves, so the order stays fully accessible and editable in the Administration and is restored automatically once the contributing plugin is reinstalled. Recalculation also succeeds, but because it recomputes the cart, a discount whose missing condition no longer matches any line item is removed (fail-closed) rather than preserved — so an order that is recalculated and saved may lose that discount line. When that happens, the recalculation result now contains a promotion-discount-unknown-condition warning (PromotionDiscountUnknownConditionError, shown as a notification in the Administration order detail page), so the discount is not removed silently.

Note that match() returning false only yields a fail-closed result for a standalone condition or inside an AndRule. Inside an OrRule/XorRule the surrounding container can still match through its other branches, and inside a NotRule the result is inverted to always-match.

Note for API consumers: writes to price-definition fields that reference an unregistered rule condition are now accepted instead of rejected, so order versioning and saves keep working. A mistyped condition name in an Admin API write is therefore no longer reported as a validation error — the condition is stored as-is and will simply never match.

Elasticsearch: Dedicated completion field for admin-search autocomplete

Admin-search autocomplete now flows through a new completion field (ngram-indexed, populated with name-shaped values per entity). The ngram subfield has been dropped from text/textBoosted so identifiers (EAN, productNumber, orderNumber, etc.) no longer feed ngram scoring — fixing a regression where a full GTIN search could be outranked by unrelated products with overlapping digit substrings.

Run bin/console es:admin:index after deploying. Identifier search works immediately on the old index; substring autocomplete is degraded to prefix-only until the reindex completes.

Type-safe subscription helpers on Extension

Shopware\Core\Framework\Extensions\Extension now exposes three static helpers — onPre(), onPost(), and onError() — that return the dispatched event name for the corresponding phase. Extensions need ::NAME constant for the methods to work.

Use them in getSubscribedEvents() instead of string concatenation or ExtensionDispatcher::pre/post/error():

php
public static function getSubscribedEvents(): array
{
    return [
        ResolveListingExtension::onPre()  => 'method1',
        ResolveListingExtension::onPost() => 'method2',
        ResolveListingExtension::onError() => 'method3',
    ];
}

Dispatchers and subscribers no longer have to concatenate event-name strings - it gives type safety, IDE autocomplete, and rename-refactor support. Also subscribers don't have to depend on ExtensionDispatcher.

The previous styles — MyExtension::NAME . '.post' and ExtensionDispatcher::post(MyExtension::NAME) — continue to work and are not deprecated. No migration is required.

Telemetry metrics evolution

The telemetry metrics abstraction behind the TELEMETRY_METRICS feature flag received several improvements ahead of stabilization in 6.8. See ADR 2026-04-23 for the full reasoning.

  • Breaking: MetricTransportInterface now requires a flush() method. Implement it as a no-op if the transport does not need lifecycle management. A new TelemetryFlushListener calls flush() on kernel.terminate, console.terminate, and (throttled) on WorkerRunningEvent so emissions from long-running workers reach the backend.
  • Global kill-switch shopware.telemetry.metrics.enabled disables emission and removes services tagged shopware.telemetry.subscriber / shopware.telemetry.periodic_metric_collector via a compiler pass — zero overhead when off.
  • Per-label validation policies: each label in a metric definition must declare either allowed_values or policy: open. Unknown values are handled per policy (replace / discard / open), with type-aware defaults (additive types replace, gauges discard). Unknown label names throw in dev/test and log at error level in production; replacements log at notice level in dev/test so typos like GETT vs GET surface during development.
  • PeriodicMetricCollectorInterface: tag a service with shopware.telemetry.periodic_metric_collector to have its metrics collected by the telemetry.collect_periodic_metrics scheduled task (default 5 minutes, tunable via the standard scheduled-task administration). Useful for expensive aggregations and info metrics.
  • New Telemetry facade: inject Telemetry to call emit(ConfiguredMetric) and instrument(callback, DurationMetric?, Span?) for combined duration metrics and profiler spans through a single entry point.
  • Config cleanup: allow_unknown_labels, allow_unknown_label_values, and enable_internal_metrics are deprecated (superseded by per-label policies and per-metric enabled).

Auto-resend double opt-in confirmation email on failed login

When a customer with an unconfirmed double opt-in account tries to log in, Shopware now automatically resends the confirmation email if the original was sent more than a configurable interval ago.

The interval is controlled by the new system config setting core.loginRegistration.doubleOptInResendInterval (default: 24 hours). Setting it to 0 disables the auto-resend entirely.

Successful password recovery now also confirms an unconfirmed double opt-in customer account, because completing the recovery flow proves access to the account email address.

Standardized CLI JSON output flag

CLI commands now consistently use --format json to request JSON output. The previously used --json and --output json options are deprecated and will be removed in Shopware 6.8.0.0.

Affected commands:

  • bin/console user:list --jsonbin/console user:list --format json
  • bin/console app:list --jsonbin/console app:list --format json
  • bin/console plugin:list --jsonbin/console plugin:list --format json
  • bin/console dal:validate --jsonbin/console dal:validate --format json
  • bin/console sales-channel:list --output jsonbin/console sales-channel:list --format json

cache:watch:delayed shuts down gracefully

The cache:watch:delayed command now stops cleanly on SIGINT/SIGTERM instead of being killed mid-loop, and exposes a configurable --interval option (microseconds) for the poll frequency.

New sha256 Twig filter

A new sha256 Twig filter is available alongside the existing md5 filter. Both accept strings and arrays (arrays are JSON-encoded before hashing) and return the hex-encoded hash.

Variants can now be searched by parent product name

The new parent.name search field allows variants to be found through their parent product name and ranked independently from the variant's own name.

The field is disabled by default. Enable parent.name in the product search configuration to make this behavior active and adjust its ranking there.

Reduced product data in listings via description teaser

Product listings can now load a shortened, HTML-free excerpt of the product description instead of the full text, which significantly reduces database load, transfer size and memory usage for catalogs with large descriptions. Previously the complete description was loaded for every product box even though the storefront only displays a few clamped lines.

This reduced loading is enabled for fresh installations and disabled for existing shops, which keep the full listing loading on update and can opt in per sales channel via the new core.listing.partialDataLoading setting (Settings > Products). When enabled, the product listing route loads a curated, reduced field set covering the default product boxes; listing products are then partial entities. Only enable it if your theme and extensions work with the reduced product data in listings.

A new read-only, translatable descriptionTeaser field is available on product (and product_translation). It is derived from the description on write (HTML stripped, truncated to 512 characters) and exposed via the Store and Admin API. The stripping is configurable through the html_sanitizer field set product_translation.descriptionTeaser. Existing products are backfilled asynchronously: the migration schedules the product.description_teaser.indexer, which runs over the message queue after the update (or manually via bin/console dal:refresh:index).

Agentic Commerce product export and tracking classes deprecated

The following classes related to Agentic Commerce product exports, providers, and sales channel tracking are deprecated and will be removed in Shopware 6.8.0:

  • Shopware\Core\Content\ProductExport\Provider\AbstractAgenticCommerceProductExportProvider
  • Shopware\Core\Content\ProductExport\Provider\AgenticCommerceProductExportProviderRegistry
  • Shopware\Core\Content\ProductExport\Provider\GoogleProductExportProvider
  • Shopware\Core\Content\ProductExport\Provider\OpenAiProductExportProvider
  • Shopware\Core\Content\ProductExport\Validator\JsonlRowParser
  • Shopware\Core\Content\ProductExport\Validator\OpenAiProductExportValidator
  • Shopware\Core\Content\ProductExport\Validator\GoogleProductExportValidator

This functionality will be available in the Agentic Commerce extension (SwagAgenticCommerce) instead.

Administration

sw-select-field forwards aria-label to the native select

The deprecated sw-select-field now passes through aria-label and aria-labelledby attributes to the underlying native <select> element. Previously these attributes were applied to the wrapping field component but never reached the form control, leaving selects without an accessible name (e.g. the range picker of sw-chart-card). Plugins that render a sw-select-field without a visible <label> can now give it an accessible name by passing aria-label / aria-labelledby.

Cache-relevant extension configuration fields

As a follow-up to Reduced HTTP cache invalidation on system config changes, plugin and app Resources/config/config.xml files can now mark fields that affect cached storefront output with the cache-relevant="true" attribute on <input-field> or <component>.

When a marked field is changed in the Administration system config renderer, the save request explicitly sends silent=false, so HTTP cache entries tagged with system.config-{salesChannelId} are invalidated. Unmarked fields keep the default system config write behavior.

Storefront icon cache and speculation rules can be configured per sales channel

The Storefront settings Administration page now allows the icon cache and speculation rules settings (core.storefrontSettings.iconCache and core.storefrontSettings.speculationRules) to be configured per sales channel. core.storefrontSettings.asyncThemeCompilation remains a global setting and was moved into a separate Theme configuration card.

The storefront runtime now resolves the icon cache setting with the active sales channel id, matching the sales-channel-aware speculation rules lookup. The old sw_settings_storefront_smtp_settings block is deprecated and will be removed in v6.8.0.

Analytics settings split into Configuration and Tracking cards

The analytics settings view in sw-sales-channel-detail-analytics was split into two cards: Configuration (general settings like tracking ID, active state, anonymize IP) and Tracking (order tracking, offcanvas cart tracking, enhanced conversions).

New extensible Twig blocks sw_sales_channel_detail_analytics_configuration, sw_sales_channel_detail_analytics_tracking, sw_sales_channel_detail_analytics_tracking_description, and sw_sales_channel_detail_analytics_fields_enhanced_conversions have been added.

Rule Builder cart total condition labels adjusted

Rule Builder cart total condition labels now describe more clearly which cart value they evaluate. The internal condition names remain unchanged for backwards compatibility.

Internal nameEN old -> newDE old -> newWhat it checks
cartCartAmountGrand total -> Cart total (incl. shipping)Gesamtsumme -> Warenkorb-Gesamtsumme (inkl. Versand)cart.price.totalPrice - final cart price incl. shipping/tax/discounts
cartPositionPriceTotal -> Cart sum of items (excl. shipping)Summe -> Summe der Positionen (ohne Versand)cart.price.positionPrice - sum of all items, no shipping
cartGoodsPriceSubtotal of all items -> Subtotal of goods (excl. discounts/fees)Zwischensumme aller Positionen -> Zwischensumme der Warenpositionen (ohne Rabatte/Zuschläge)Sum of goods item prices, excl. shipping/promotions
cartTotalPurchasePriceTotal of all purchase prices -> Sum of purchase pricesSumme aller Einkaufspreise -> Summe der EinkaufspreiseSum of purchase/cost prices across all items
cartLineItemTotalPriceItem subtotal -> Item total (qty × price)Positionszwischensumme -> Positionssumme (Menge × Preis)One item's total, quantity multiplied by unit price
cartLineItemGoodsTotalTotal quantity of all products -> Total product quantity (units)Gesamtanzahl aller Produkte -> Gesamtmenge der Produkte (Stück)Total unit count of goods in the cart
cartGoodsCountTotal quantity of distinct products -> Number of distinct productsGesamtanzahl unterschiedlicher Produkte -> Anzahl unterschiedlicher ProdukteNumber of distinct products in the cart

Rule Builder quantity condition labels disambiguated

Internal nameEN old -> newDE old -> newWhat it checks
cartLineItemWithQuantityItem quantity -> Item with quantityPositionsanzahl -> Position mit MengeA specific selected product's quantity
cartLineItemsInCartCountQuantity of distinct items -> Number of distinct itemsAnzahl unterschiedlicher Positionen (unchanged)Number of distinct line items (all types)
promotionsInCartCountQuantity of discounts -> Number of discountsAnzahl der Rabatte (unchanged)Number of discount line items

sw-data-grid column labels fall back to the default locale

Column headers and the column visibility settings in sw-data-grid now resolve their labels against the configured i18n fallback locale when the snippet is missing in the current locale, instead of rendering the raw snippet key. This matches the behavior users expect when a translation is only available in English.

Rule builder shows per-field errors on conditions

Invalid condition inputs are now highlighted individually with a list of the affected fields below the row. All reversed date ranges are reported in one save instead of one at a time.

Reworked timeframe options in sw-date-filter

The order date filter dropdown now offers a 15-entry list, in display order:

  1. Today
  2. Yesterday
  3. Current week
  4. Last 7 days
  5. Previous week
  6. Current month
  7. Last 30 days
  8. Previous month
  9. Current quarter
  10. Previous quarter
  11. Last 3 months
  12. Last 6 months
  13. Last 12 months
  14. Current year
  15. Previous year

"Current ..." entries span the start of the period through today (e.g., current quarter = first day of the quarter through today). "Previous ..." entries cover the full prior period (e.g., previous quarter = the three months before this one). "Last N days/months" remain rolling windows ending today, with calendar-month math (and last-day-of-month clamping) for the months variants so May 31 - 3 months lands on Feb 29 (leap) or Feb 28 (non-leap) rather than rolling forward to March 3.

The previous rolling lastDay (-1) and lastYear (-365) entries are no longer in the dropdown, but saved filter states keep working: the component now aliases -1 to yesterday and -365 to last12Months on both hydration and programmatic selection. The persisted from/to are preserved so existing filters continue to resolve the same data, while the dropdown label catches up to the new vocabulary. All boundaries continue to be normalized to the user's timezone.

Support test file splitting

Administration Jest tests can now be split into multiple files using *.spec/ directories. ESLint now warns for Administration test files with 500 lines or more and errors for test files with 1000 lines or more.

App action button icons are aligned in Administration context menus

App action buttons that use an app manifest icon now render the icon at the normal context-menu size and align it on the same row as the action label. Previously, the app logo could render oversized or stacked above the action text in Administration action menus, for example on order detail pages.

Product variants are easier to distinguish in sw-entity-multi-id-select

sw-entity-multi-id-select now displays product variant option details for product repositories in the selected labels and dropdown results. This helps extensions and plugin configuration UIs that let merchants select multiple products, because variants with inherited product names no longer appear as identical entries.

Outside clicks in dropdowns are identified correctly

Administration dropdowns now identify outside clicks correctly when the browser reports a click target outside the dropdown even though the pointer is still over the dropdown.

Resolving download errors by renaming media

When merchants rename a media file, its URL automatically updates so they can download it without issues.

Agentic Commerce Administration components deprecated

The following Administration component, methods, and computed properties are deprecated and will be removed in Shopware 6.8:

sw-agentic-commerce-tracking-config — entire component deprecated.

sw-sales-channel-modal-grid:

  • computed salesChannelRepository
  • method isAgenticCommerceSalesChannelType()
  • method showAgenticCommerceType()

sw-sales-channel-detail:

  • provide swSalesChannelDetailGetAgenticCommerceExportConfig
  • data agenticCommerceExportConfig
  • computed isAgenticCommerce
  • computed defaultAgenticCommerceExportConfig
  • method validateAgenticCommerceExportConfig()
  • method loadAgenticCommerceExportConfig()
  • method saveAgenticCommerceExportConfig()

sw-sales-channel-create-base:

  • method prefillAgenticCommerceDefaults()

sw-sales-channel-detail-base:

  • inject swSalesChannelDetailGetAgenticCommerceExportConfig
  • computed isAgenticCommerce
  • computed resolvedAgenticCommerceExportConfig
  • method getAgenticCommerceExportElementBind()
  • method getAgenticCommerceExportCardTitle()
  • method getAgenticCommerceExportCardPositionIdentifier()
  • method onAgenticCommerceExportFieldUpdate()

sw-sales-channel-detail-product-comparison:

  • computed isAgenticCommerce

This functionality will be available in the Agentic Commerce extension (SwagAgenticCommerce) instead.

App System

[Opt-in] Webhook delivery rework

Webhook delivery moves to a new dedicated webhook Messenger transport, rolled out behind the WEBHOOKS_REWORK feature flag. When the flag is disabled (which is the default), the webhook transport forwards to async and Messenger owns retries. When the flag is enabled, every webhook is persisted to a database-backed outbox before the first HTTP attempt, and Shopware controls when and how often each delivery is retried.

With the flag enabled:

  • Failed deliveries are retried for up to four hours. Failures back off on a fixed 5s → 30s → 5min → 30min → 4h schedule, so a brief DNS outage or upstream restart does not exhaust retries before the endpoint recovers.
  • Synchronous deliveries are audited. Deliveries that bypass the queue — those triggered by the admin worker or by forced-sync app lifecycle calls — produce the same audit row as async deliveries, so failures on those paths are inspectable in the database and via the Admin API.
  • In-flight deliveries survive worker crashes. If a worker dies while sending a webhook, the next worker picks up the in-flight delivery and retries it.
  • Identity headers on every HTTP POST. Every request carries X-Shopware-Event-Id, X-Shopware-Sequence, and X-Shopware-Attempt headers plus a source.sequence field in the body. Consumers can use them to deduplicate retries and reorder events independent of HTTP arrival order. The same headers ship for every webhook, regardless of how it is delivered.

Enabling the flag requires configuration changes — the worker consume command must list the new webhook transport, and shopware.admin_worker.transports may need updating if it was overridden. Rolling the flag back off also has its own steps. See UPGRADE-6.7.md for the full procedure.

Tracked in shopware/shopware#16560.

Tax provider priority is preserved across app updates

An app tax provider's priority is now only seeded from the manifest when the provider is first installed. App updates no longer touch the priority, so the merchant's manual ordering is retained.

Hosting & Configuration

Google Storage supports application default credentials

Google Storage filesystem configurations can now omit keyFile and keyFilePath. When neither option is configured, Shopware lets the Google Cloud PHP SDK resolve credentials through Application Default Credentials, such as GOOGLE_APPLICATION_CREDENTIALS, local ADC files, or attached service accounts in Google Cloud environments. See Google's PHP client authentication guide for the PHP library lookup behavior.

Critical Fixes

Admin worker no longer blocks same-session API requests on PHP session locks

Fixed a session-locking issue that could slow down concurrent Administration requests when the browser-based admin worker is used together with native PHP file session storage. In that setup, an admin queue worker request could initialize the current PHP session while consuming messages and keep the session file locked until the long-poll request returned. Concurrent Admin API requests from the same browser session, for example sync or save requests, no longer wait for that admin worker session lock.

Fixed bugs

  • Prevented Shopware Administration from crashing after Composer installs Twig 3.28 by blocking the incompatible dependency version (#18034)
  • Stopped product purchase prices from being exposed in customer-facing Store API order line item payloads (#17583)
  • Prevented checkout orders from returning a 500 error when Elasticsearch/OpenSearch is temporarily unavailable after stock changes (#16974)
  • Fixed storefront checkout so unavailable payment or shipping methods are replaced correctly when Checkout Gateway rules block the selected method (#16780)
  • Fixed product exports so feeds are no longer empty or incomplete when variants are excluded from export output (#17083)

See all fixed bugs in this release: https://github.com/shopware/shopware/milestone/38?closed=1

Credits

Thanks to all diligent friends for helping us make Shopware better and better with each pull request!

See all contributors on this page: https://github.com/shopware/shopware/releases/tag/v6.7.12.0#Contributors

More resources

Get in touch

Discuss about decisions, bugs you might stumble upon, etc in our community discord. See you there 😉

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