Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
293 changes: 293 additions & 0 deletions src/6.7/6.7.7.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
---
nav:
title: v6.7.7.0
meta:
date: "2026-02-02"
---

# 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](https://symfony.com/blog/symfony-7-4-0-released) 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 JOIN`s 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](adr/2020-11-19-dal-join-filter.md), this would look like:

```php
$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.name`
* `custom_field.type`
* `custom_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.states` field is deprecated in favor of `order_line_item.payload.product_type`.
- `\Shopware\Core\Checkout\Cart\LineItem\LineItem::$states` is deprecated in favor of `\Shopware\Core\Checkout\Cart\LineItem\LineItem::$payload['productType']`.
- The `LineItemProductStatesRule` is deprecated in favor of the new `LineItemProductTypeRule`.
- The `StatesUpdater` service and its related dispatched events (`ProductStatesBeforeChangeEvent`, `ProductStatesChangedEvent`) are deprecated.
- A new parameter `shopware.product.allowed_types` was 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](adr%2F2025-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:

```php
$parameter = $request->get($parameterName, $default);
```

After:

```php
$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:

```php
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`:

* `searchTerm` prop and watcher will be removed in v6.8.0.0
* `getList()` method: `searchTerm` variable will be replaced with `this.term` in v6.8.0.0
* `@page-change` handler will change to `onPageChange` in v6.8.0.0

The following deprecations apply to `sw-mail-template-index`:

* The `listing` mixin will be removed in v6.8.0.0
* `term` data property will be removed in v6.8.0.0
* `onChangeLanguage` method: 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 `_noStore` route attribute to apply `no-store` directive in Cache-Control header.
* `Cache-Control` header set by policies is sent to the client for all responses, even when no reverse proxy is enabled. Previously, headers were replaced with `no-cache` when 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`, and `remove_from_cart` have been enriched with additional data such as `currency`, `value`, `item_brand`, and a hierarchical `item_category` structure.
- Furthermore, new events for `add_to_wishlist`, `remove_from_wishlist`, `view_cart`, `add_shipping_info`, and `add_payment_info` have 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_list` and `add_to_cart` events 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:

1. The offcanvas cart will **not open automatically** after adding items to the cart
2. A success message will be shown instead
3. 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](https://github.com/shopware/shopware/issues/14351) fix: flyout navigation correctly closes on mouseleave :contentReference[oaicite:1]{index=1}
* [#14293](https://github.com/shopware/shopware/issues/14293) fix: visual bugs in after sales :contentReference[oaicite:2]{index=2}
* [#14380](https://github.com/shopware/shopware/issues/14380) fix: Critical dive canvas resize bug. :contentReference[oaicite:3]{index=3}
* [#14365](https://github.com/shopware/shopware/issues/14365) fix: Allow filter zero and negative value for stock :contentReference[oaicite:4]{index=4}
* [#14318](https://github.com/shopware/shopware/issues/14318) fix: theme_runtime_config contains duplicate entries after theme install/uninstall :contentReference[oaicite:5]{index=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](https://github.com/shopware/shopware/compare/v6.7.6.2...v6.7.7.0) to the former version
* [Changelog on GitHub](https://github.com/shopware/shopware/releases/tag/v6.7.7.0) for this version.
* [Release News corporate blog post](https://www.shopware.com/en/news/shopware-6-release-news-february-2026/)
* [Installation overview](https://developer.shopware.com/docs/guides/installation/)
* [Update from a previous installation](https://developer.shopware.com/docs/guides/installation/template.html#update-shopware)

## Get in touch

Discuss about decisions, bugs you might stumble upon, etc in our [community discord](https://chat.shopware.com). See you there ;)