Release notes Shopware 6.7.7.0
Abstract
Shopware 6.7.7.0 as a minor release delivers a strong mix of performance improvements, developer-focused enhancements and stability fixes. This release upgrades the framework to Symfony 7.4, introduces significant DAL query performance optimizations, enhances cache invalidation and search indexing, and improves media handling across the platform. Administrators and storefront users benefit from usability and accessibility improvements, while developers gain new extensibility options and clearer deprecation paths.
In addition to these improvements, this version includes ~120 closed issues, covering bug fixes and other merged changes.
System requirements
- tested on PHP 8.2, 8.4 and 8.5
- tested on MySQL 8 and MariaDB 11
Improvements
Symfony 7.4 update
All symfony packages have been updated to version 7.4. Take a look at the Symfony 7.4 release post for more information. Especially note that Symfony now requires php-redis extension v6.1 or higher: https://github.com/symfony/symfony/blob/7.4/UPGRADE-7.4.md#cache. If you note compatibility issues with the Redis extension please check the installed version php-redis.
Changed maintenance mode redirect
After maintenance ends, users are now redirected back to the page they were on before maintenance. Previously, users were always redirected to the shop homepage.
Support of media paths with up to 2046 characters
Previously the maximum length for media paths was limited to 255 characters (due to default StringField limit) while the database field already supported up to 2046 characters. This limitation has now been lifted and media paths can be up to 2046 characters long.
Configurable Custom Field Searchability
Custom fields are now not searchable by default. To make a custom field searchable, you need to enable the "Include in search" option in the custom field detail modal when creating or updating a custom field in Settings > System > Custom fields. This change helps optimize index storage size and improve search performance, especially for stores with many custom fields.
Important: When enabling searchability for an existing product custom field, you must rebuild the search index or update the products manually to include the custom field data in search results.
Media Model Viewer
From now on you are able to inspect your 3D models directly in the Media module in the Administration. Simply select a model file and you will find an interactive 3D viewer in the Preview collapsable in the item sidebar on the right. This new component is called sw-model-viewer.
API
Improved tagged based cache invalidation
Next routes now support cache tagging, enabling automatic invalidation when relevant entities are written:
/store-api/breadcrumb/{id}/store-api/media/store-api/product/{productId}/find-variant/store-api/product/{productId}/cross-selling
Core
Rework of DAL query generation for nested filters groups
The DAL criteria builder has been adjusted to generate EXISTS subqueries instead of LEFT JOINs for nested filter groups.
Previously, each level of nested filters resulted in an additional LEFT JOIN, even when the join was only required to check for the existence of a related entity subject to some filter. In complex criteria trees with multiple filters on the same entity, this led to an exponential explosion of joins and significant performance degradation (e.g., the same table being joined multiple times only to evaluate existence conditions).
An example of this is a query such as "find orders that have a line item of type A and one of type B and one of type C". According to aadr/2020-11-19-dal-join-filter.md, this would look like:
$criteria->addFilter(
new EqualsFilter('lineItems.type', 'product'),
new EqualsFilter('lineItems.type', 'custom'),
new EqualsFilter('lineItems.type', 'other'),
);Previously, the generated query would LEFT JOIN order_line_item multiple times onto order, causing the query to be extremely slow. The new EXISTS checks prevent this, making the query much faster.
Introduce Immutable DAL flag
A new Immutable flag is available for Data Abstraction Layer fields. Fields marked as immutable can be set during entity creation but cannot be updated later. This prevents accidental renames of technical identifiers that other subsystems rely on. Core entities now using the flag include:
custom_field.namecustom_field.typecustom_field_set.name
Trying to update these columns now results in a WriteConstraintViolationException with the message The field foo is immutable and cannot be updated., giving developers clear feedback when attempting to change these values. If the value is not set in the payload, or the value won't change, no exception is thrown.
Performance Improvement for ProductCategoryDenormalizer
The SQL Query inside the ProductCategoryDenormalizer has been optimized to run faster, especially on large catalogues. Previously MySql needed to perform a full table scan based on the where condition, now the result set is already limited by indexed columns. This lead to performance improvements from up to 3s for the query down to less than 1ms on large catalogues (3000%).
Deprecation of product states in favor of the new product type
The product.states field is deprecated and will be removed in the next major release. A new field product.type was introduced to clearly indicate whether a product is digital or physical, or other types registered by third-party developers.
As part of this change, the following deprecations were made:
- The
order_line_item.statesfield is deprecated in favor oforder_line_item.payload.product_type. \Shopware\Core\Checkout\Cart\LineItem\LineItem::$statesis deprecated in favor of\Shopware\Core\Checkout\Cart\LineItem\LineItem::$payload['productType'].- The
LineItemProductStatesRuleis deprecated in favor of the newLineItemProductTypeRule. - The
StatesUpdaterservice and its related dispatched events (ProductStatesBeforeChangeEvent,ProductStatesChangedEvent) are deprecated. - A new parameter
shopware.product.allowed_typeswas introduced to allow third-party developers to register additional product types. - For more details, please refer to the 2025-11-14-introduce-product-type-and-deprecate-states.md
If you are using the rule LineItemProductStatesRule, product stream filters, or product listing filters that rely on product.states, you should update them to use the new product.type field instead. If you create digital products using admin api, you should explicitly set the type field to digital when creating new products instead of relying on backend handling.
New RequestParamHelper
Symfony deprecated the "magic" Request::get() method, which was used to retrieve parameters from the request, by checking the attribute, query or request parameter bags. For easier backward compatibilty we backported the old behaviour in the new RequestParamHelper class, however, it should only be used in explicit cases, where the parameter could be in any of those parameter bags. The best practice is to check the explicit parameter bag, where you expect the parameter to be. However, as we have a lot of API routes that support being called by GET and POST methods both, the helper is handy in such cases.
Before:
$parameter = $request->get($parameterName, $default);After:
$parameter = RequestParameterHelper::get($request, $parameterName, $default);To provide full backward compatibility, the helper currently also checks the attribute bag for the parameter first. However, it should be possible to strictly differentiate between request attributes (which are generally controlled and set by the application itself) and input parameters (which are provided by the client, and based on how they are passed are either part of the query bag or the request bag) in the future. Therefore the check of the attribute bag is deprecated and will be removed in the next major release. When you need to get a value from the request attributes, you should use the Request::attributes->get() method directly. In case you used to set request attributes to override specific parameters, you should instead overwrite the parametes in the query or request parameter bags directly.
The TranslationLoader class is now decoratable
The TranslationLoader class extends from the new AbstractTranslationLoader class and implements the decoratable pattern. This allows third-party developers to decorate the loader to add custom logic when a translation is loaded.
DomainExceptions don't create \RuntimeException anymore
All factory methods for domain exceptions now return specific exception classes instead of creating a generic \RuntimeException. Changing the type of the thrown exception from \RuntimeException to a specific domain exception is not considered a breaking change, since all Domain Exceptions extend from \RuntimeException.
This means code like this will stay valid:
try {
$this->someService->willThrowDomainException();
} catch (\RuntimeException $e) {
// handle exception
}Additionally, all changed factory methods were marked as deprecated, because the \RuntimeException return type will be removed in the next major release. This affects the following exception factory methods:
DataAbstractionLayerException::cannotBuildAccessor(...)DataAbstractionLayerException::onlyStorageAwareFieldsAsTranslated(...)DataAbstractionLayerException::onlyStorageAwareFieldsInReadCondition(...)DataAbstractionLayerException::primaryKeyNotStorageAware(...)DataAbstractionLayerException::missingTranslatedStorageAwareProperty(...)DataAbstractionLayerException::noTranslationDefinition(...)DataAbstractionLayerException::missingVersionField(...)DataAbstractionLayerException::unexpectedFieldType(...)WebhookException::invalidDataMapping(...)WebhookException::unknownEventDataType(...)
More fine-grained caching control in HttpCacheCookieEvent
A new doNotStore property was added to the HttpCacheCookieEvent to allow fine-grained control over caching behavior. This new property allows preventing the current response from being stored in the cache. This behaviour differs from the existing ìsCacheable` property, which will also prevent the following requests from that session being cached.
Logging for invalidated cache tags
Added logging for invalidated cache tags at the info level, with the ability to enable or disable the logging via configuration for debugging and transparency.
Removed CacheInvalidationSubscriber::getChangedPropertyFilterTags due to performance issues
The getChangedPropertyFilterTags method has been removed from CacheInvalidationSubscriber due to performance issues where it could cause invalidation storms by selecting all product IDs for popular property options.
Changing a property group or option will no longer automatically invalidate product and product list caches. It's recommended to rely on TTLs for bigger shops. If you experience issues after changing a property group, a manual cache clear may be required.
Administration
Deprecations in mail template components
The mail template index will be split into separate tabs for templates and headers/footers in v6.8.0.0.
The following deprecations apply to sw-mail-template-list and sw-mail-header-footer-list:
searchTermprop and watcher will be removed in v6.8.0.0getList()method:searchTermvariable will be replaced withthis.termin v6.8.0.0@page-changehandler will change toonPageChangein v6.8.0.0
The following deprecations apply to sw-mail-template-index:
- The
listingmixin will be removed in v6.8.0.0 termdata property will be removed in v6.8.0.0onChangeLanguagemethod: the if/else block will be replaced with just the if-branch logic in v6.8.0.0
Storefront
Cookie consent now language-aware
The cookie consent banner now tracks cookie configuration per language. Previously, switching languages would cause the cookie banner to reappear because the configuration hash changed due to translated cookie descriptions. Now, switching back to a previously accepted language will not show the banner again.
The Store API endpoint /store-api/cookie-groups now includes a languageId field in the response.
New window.activeNavigationPathIdList variable
A new global JavaScript variable window.activeNavigationPathIdList is now available, containing the IDs of parent categories for the current page. This can be used by plugins or themes to implement custom navigation highlighting.
Improved cookie consent dialog UI and accessibility
The cookie consent dialog now uses toggle switches instead of checkboxes for a more modern look. Additionally, accessibility improvements were made by adding proper ARIA attributes (role="switch", aria-disabled, aria-labelledby) and converting links to semantic buttons where appropriate.
HTTP caching policies update
The following changes are relevant when HTTP caching policies feature is enabled (CACHE_REWORK or v6.8.0.0 feature flag):
- HTTP caching policy system now takes into account
_noStoreroute attribute to applyno-storedirective in Cache-Control header. Cache-Controlheader set by policies is sent to the client for all responses, even when no reverse proxy is enabled. Previously, headers were replaced withno-cachewhen no reverse proxy was configured. Important: Verify your cache policy configuration is appropriate for client-side caching, as browser caches cannot be invalidated on-demand unlike reverse proxies that use tag-based invalidation.
First tap on iOS Safari did not trigger call-to-action buttons on product detail page
Fixes an issue on iOS Safari where the first tap does not trigger the desired action on the product detail page after scrolling over the image gallery. The touchmove event listener was removed from zoom-modal.plugin.js because it stopped the tap/click event. A regular click event is used instead to open the Zoom-Modal. The browser itself can determine via the click event if the user is still scrolling or clicking/taping.
Google Analytics 4 Integration Update
The Google Analytics integration has been updated to align with GA4 standards, enhancing e-commerce tracking capabilities.
- The event parameters for
add_to_cart,begin_checkout,purchase,view_item, andremove_from_carthave been enriched with additional data such ascurrency,value,item_brand, and a hierarchicalitem_categorystructure. - Furthermore, new events for
add_to_wishlist,remove_from_wishlist,view_cart,add_shipping_info, andadd_payment_infohave been implemented to provide a more comprehensive view of user interactions. - The checkout funnel now tracks shipping and payment method selections, including when users change their selections.
- The
view_item_listandadd_to_cartevents now fire when users navigate through product listings via pagination or apply filters, not just on initial page load.
New Configuration: Track Offcanvas Cart
A new configuration option Track offcanvas cart has been added to the Sales Channel Analytics settings. When enabled, the view_cart GA4 event will fire whenever the offcanvas cart is opened or its content is updated (e.g., quantity changes, product removals, promotions).
New Configuration: Open Offcanvas Cart After Add to Cart
A new configuration option Open offcanvas cart after adding a product has been added to the Cart settings (Settings → Shop → Cart). This setting is enabled by default. When disabled:
- The offcanvas cart will not open automatically after adding items to the cart
- A success message will be shown instead
- The cart widget in the header will still update to show the new item count
Recommended for accurate funnel tracking: Disable "Open offcanvas cart after adding a product" and enable "Track offcanvas cart". This ensures view_cart events only fire when users intentionally click the cart button, providing accurate funnel metrics.
Critical Fixes
Flash messages are not cached anymore
As soon as a flash message is displayed, the response won't be stored in the HTTP cache anymore, thus preventing the message from being displayed to other users. Additionally, the cache will be passed as soon as there is a flash message that still needs to be displayed. This ensures that flash messages are always displayed on the next request, and not only on the next request to an uncached page.
Fixed bugs
- #14351 fix: flyout navigation correctly closes on mouseleave :contentReference[oaicite:1]
- #14293 fix: visual bugs in after sales :contentReference[oaicite:2]
- #14380 fix: Critical dive canvas resize bug. :contentReference[oaicite:3]
- #14365 fix: Allow filter zero and negative value for stock :contentReference[oaicite:4]
- #14318 fix: theme_runtime_config contains duplicate entries after theme install/uninstall :contentReference[oaicite:5]
See all fixed bugs in this release: https://github.com/shopware/shopware/milestone/25?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.7.0#Contributors
More resources
- Detailed diff on Github to the former version
- Changelog on GitHub for this version.
- Release News corporate blog post
- Installation overview
- Update from a previous installation
Get in touch
Discuss about decisions, bugs you might stumble upon, etc in our community discord. See you there 😉