NOTE: All the breaking changes described here can be already opted in by activating the v6.7.0.0
feature flag on previous versions.
We are switching the build system for our administration from webpack to vite.
This means that when your plugins depends on a custom webpack.config.js
file, you'll need to migrate it to a vite.config.js
file.
More information about how to upgrade will be available soon.
Additionally, this means that you will need to distribute a separate plugin version starting for 6.7, when you extend the administration to distribute the correct build files. For more information please take a look at the docs.
Note: This change can be activated separately with the ADMIN_VITE
feature flag.
The Vue 2 compatibility layer has been removed from the administration. This means that all components that still rely on Vue 2 features need to be updated. This ensures that our administration stays future-proof and we can make use of the most recent Vue 3 features.
For detailed explanation of what was covered by the compatibility layer and what needs to be updated, please refer to the Vue docs.
Note: This change can be activated separately with the DISABLE_VUE_COMPAT
feature flag.
For Vue 3 the default state management library has become Pinia, therefore we are migrating from Vuex to Pinia. to stay as close to the default as possible.
When you use default stores in your plugin you need to switch from Shopware.State
(Vuex) to Shopware.Store
(Pinia).
Adding your own Vuex stores is still possible, however it is recommended that you switch to Pinia as well.
Here is an example of how to switch from Vuex to Pinia:
// Old Vuex implementation
Shopware.State.registerModule('example', {
state: {
id: '',
},
getters: {
idStart(state) {
return state.id.substring(0, 4);
}
},
mutations: {
setId(state, id) {
state.id = id;
}
},
actions: {
async asyncFoo({ commit }, id) {
// Do some async stuff
return Promise.resolve(() => {
commit('setId', id);
return id;
});
}
}
});
// New Pinia implementation
// Notice that the mutation setId was removed! You can directly modify a Pinia store state after retrieving it with Shopware.Store.get.
Shopware.Store.register({
id: 'example',
state: () => ({
id: '',
}),
getters: {
idStart: () => this.id.substring(0, 4),
},
actions: {
async asyncFoo(id) {
// Do some async stuff
return Promise.resolve(() => {
this.id = id;
return id;
});
}
}
});
For more information refer to the docs.
Note: Those changes can be activated separately with the cache_rework
feature flag.
The cache invalidation will be delayed by default. This means that the cache will be invalidated in regular intervals and not immediately.
This will lead to better cache hit rates and way less (duplicated) cache invalidations, which will improve efficiency and scalability of the system.
As this feature is now active by default the previous shopware.cache.invalidation.delay
configuration is removed.
The default interval is 5 min, this can be changed by adjusting the run interval of the shopware.invalidate_cache
scheduled task.
If you sent an API request with critical information, where the cache should be invalidated immediately, you can set the sw-force-cache-invalidate
header on your request.
POST /api/product
sw-force-cache-invalidate: 1
To manually clear all the stale caches you can either run the cache:clear:delayed
command or use the /api/_action/cache-delayed
API endpoint.
bin/console cache:clear:delayed
DELETE /api/_action/cache-delayed
For debugging there is the cache:watch:delayed
command available, to watch the cache tags that are stored in the delayed cache invalidation queue.
bin/console cache:watch:delayed
The Store-API route caching has been removed. This means that the Cached*Route
classes will be removed.
This solves some weird states when the HTTP-Cache was invalidated separately from the route cache.
Additionally, the cache hit rate for the Store-API was low, so the performance impact should be minimal, but the amount of cache items and cache invalidations will be reduced.
This overall should lead to more effective cache resource usage.
The header and footer are now loaded via ESI.
This allows to cache the header and footer separately from the rest of the page.
Two new routes \header
and \footer
were added to receive the rendered header and footer.
The rendered header and footer are included into the page with the Twig function render_esi
, which calls the previously mentioned routes.
Two new templates src/Storefront/Resources/views/storefront/layout/header.html.twig
and src/Storefront/Resources/views/storefront/layout/footer.html.twig
were introduced as new entry points for the header and footer.
Make sure to adjust your template extensions to be compatible with the new structure.
The block names are still the same, so it just should be necessary to extend from the new templates.
We upgraded the following libraries to their latest versions:
- DBAL 4.x: When you are using DBAL directly, please check the upgrade guide.
- PHPUnit 11.x: You need to adjust your tests to the new PHPUnit version.
- Dompdf 3.x: Please check your document templates, if they are still rendered as expected.
- oauth2-server 9.x: We don't expect you are affected by this change on the code level, however the library does not support some requests that are not spec-compliant, look at the detailed upgrade guide.
In alignment with the European Accessibility Act (EAA) we made significant accessibility improvements.
Note: Those changes can be activated separately with the ACCESSIBILITY_TWEAKS
feature flag.
Detailed Changes
Storefront product box accessibility: Removed duplicate links around the product image in product cards
Affected template: Resources/views/storefront/component/product/card/box-standard.html.twig
The anchor link around the product image a.product-image-link
is removed and replaced with the link of the product name a.product-name
that now uses the stretched-link
helper class:
<div class="card product-box box-standard">
<div class="card-body">
<div class="product-image-wrapper">
- <a href="https://shopware.local/Example-Product/SW-01931a101dcc725aa3affc0ff408ee31">
<img src="https://shopware.local/media/a3/22/75/1731309077/Example-Product_%283%29.webp?ts=1731309077" alt="Example-Product">
- </a>
</div>
<div class="product-info">
<a href="https://shopware.local/Example-Product/SW-01931a101dcc725aa3affc0ff408ee31"
+ class="product-name stretched-link"> {# <------ stretched-link is used instead #}
Example-Product
</a>
</div>
</div>
</div>
In regard to better readability the base font-size of the storefront is updated to the browser standard of 1rem
(16px). Other text formatting is adjusted accordingly. The following variables and properties are changed:
$font-size-base
changed from0.875rem
to1rem
.$font-size-lg
changed from1rem
to1.125rem
.$font-size-sm
changed from0.75rem
to0.875rem
.$paragraph-margin-bottom
changed from1rem
to2rem
.line-height
of.quantity-selector-group-input
changed to1rem
.font-size
of.form-text
changed from0.875rem
to$font-size-base
.font-size
of.account-profile-change
changed from$font-size-sm
to$font-size-base
.font-size
of.product-description
changed from0.875rem
to$font-size-base
.line-height
of.product-description
changed from1.125rem
to$line-height-base
.height
of.product-description
changed from3.375rem
to4.5rem
.line-height
of.quantity-selector-group-input
changed to1rem
.font-size
of.main-navigation-menu
changed from$font-size-lg
to$font-size-base
.font-size
of.navigation-flyout-category-link
changed from$font-size-lg
to$font-size-base
.
The .top-bar-list-item
elements inside the "top-bar" dropdown menus will contain <button>
elements instead of a hidden <input type="radio">
elements.
Affected templates:
Resources/views/storefront/layout/header/actions/language-widget.html.twig
Resources/views/storefront/layout/header/actions/currency-widget.html.twig
<ul class="top-bar-list dropdown-menu dropdown-menu-end">
<li class="top-bar-list-item">
<label class="top-bar-list-label" for="top-bar-01918f15b7e2711083e85ec52ac29411">
<input class="top-bar-list-radio" id="top-bar-01918f15b7e2711083e85ec52ac29411" value="01918f15b7e2711083e85ec52ac29411" name="currencyId" type="radio">
£ GBP
</label>
</li>
<li class="top-bar-list-item">
<label class="top-bar-list-label" for="top-bar-01918f15b7e2711083e85ec52ac29411">
<input class="top-bar-list-radio" id="top-bar-01918f15b7e2711083e85ec52ac29411" value="01918f15b7e2711083e85ec52ac29411" name="currencyId" type="radio">
$ USD
</label>
</li>
</ul>
<ul class="top-bar-list dropdown-menu dropdown-menu-end">
<li class="top-bar-list-item">
<button class="dropdown-item" type="submit" name="currencyId" id="top-bar-01918f15b7e2711083e85ec52ac29411" value="01918f15b7e2711083e85ec52ac29411">
<span aria-hidden="true" class="top-bar-list-item-currency-symbol">£</span>
Pound
</button>
</li>
<li class="top-bar-list-item">
<button class="dropdown-item" type="submit" name="currencyId" id="top-bar-01918f15b7e2711083e85ec52ac29411" value="01918f15b7e2711083e85ec52ac29411">
<span aria-hidden="true" class="top-bar-list-item-currency-symbol">$</span>
US-Dollar
</button>
</li>
</ul>
If you are modifying the dropdown item, please adjust to the new HTML structure and consider the deprecation comments in the code.
The example below shows currency-widget.html.twig
. Inside language-widget.html.twig
a similar structure can be found.
{% sw_extends '@Storefront/storefront/layout/header/actions/currency-widget.html.twig' %}
{% block layout_header_actions_currency_widget_form_items_element_input %}
<input type="radio">
Special list-item override
{% endblock %}
{% sw_extends '@Storefront/storefront/layout/header/actions/currency-widget.html.twig' %}
{# The block `layout_header_actions_currency_widget_form_items_element_input` does no longer exist, use upper block `layout_header_actions_currency_widget_form_items_element_label` insted. #}
{% block layout_header_actions_currency_widget_form_items_element_label %}
<button class="dropdown-item">
Special list-item override
</button>
{% endblock %}
To improve the accessibility and semantics, several generic <div>
elements that are representing lists are changed to actual <ul>
and <li>
elements.
This effects the account order overview area as well as the cart line-item templates.
If you are adding custom line-item templates, please change the root element to an <li>
element:
change
<div class="{{ lineItemClasses }}">
<div class="row line-item-row">
{# Line item content #}
</div>
<div>
to
<li class="{{ lineItemClasses }}">
<div class="row line-item-row">
{# Line item content #}
</div>
<li>
If you are looping over line-items manually in your template, please change the nearest parent element to an <ul>
:
change
<div class="line-item-container-custom">
{% for lineItem in lineItems %}
{# Now renders `<li>` #}
{% sw_include '@Storefront/storefront/component/line-item/line-item.html.twig' %}
{% endfor %}
</div>
to
<ul class="line-item-container-custom list-unstyled">
{% for lineItem in lineItems %}
{# Now renders `<li>` #}
{% sw_include '@Storefront/storefront/component/line-item/line-item.html.twig' %}
{% endfor %}
</ul>
Please consider the documented deprecations inside the templates and adjust modified HTML accordingly. The overall HTML tree structure and the Twig blocks are not affected by this change.
- Account order overview
src/Storefront/Resources/views/storefront/page/account/order-history/index.html.twig
src/Storefront/Resources/views/storefront/page/account/order-history/order-detail-document-item.html.twig
src/Storefront/Resources/views/storefront/page/account/order-history/order-detail-document.html.twig
- Cart table header (Root element changed to
<li>
)src/Storefront/Resources/views/storefront/component/checkout/cart-header.html.twig
- Line-items wrapper (List wrapper element changed to
<ul>
)src/Storefront/Resources/views/storefront/page/checkout/cart/index.html.twig
src/Storefront/Resources/views/storefront/page/checkout/confirm/index.html.twig
src/Storefront/Resources/views/storefront/page/checkout/finish/index.html.twig
src/Storefront/Resources/views/storefront/page/checkout/address/index.html.twig
src/Storefront/Resources/views/storefront/page/account/order-history/order-detail-list.html.twig
src/Storefront/Resources/views/storefront/component/checkout/offcanvas-cart.html.twig
- Line-items (Root element changed to
<li>
)src/Storefront/Resources/views/storefront/component/line-item/type/product.html.twig
src/Storefront/Resources/views/storefront/component/line-item/type/discount.html.twig
src/Storefront/Resources/views/storefront/component/line-item/type/generic.html.twig
src/Storefront/Resources/views/storefront/component/line-item/type/container.html.twig
The storefront pagination component (Resources/views/storefront/component/pagination.html.twig
) is no longer using radio inputs with styled labels. Anchor links are used instead.
If you are modifying the <label>
inside the pagination template, you need to change the markup to <a>
instead. Please use one of the documented twig block alternatives inside pagination.html.twig
.
The hidden radio input will no longer be in the HTML. The current page value will be retrieved by the data-page
attribute instead of the radio inputs value.
{% sw_extends '@Storefront/storefront/component/pagination.html.twig '%}
{% block component_pagination_first_input %}
<input type="radio"
{% if currentPage == 1 %}disabled="disabled"{% endif %}
name="p"
id="p-first{{ paginationSuffix }}"
value="1"
class="d-none some-special-class"
title="pagination">
{% endblock %}
{% block component_pagination_first_label %}
<label class="page-link some-special-class" for="p-first{{ paginationSuffix }}">
{# Using text instead of icon and add some special CSS class #}
First
</label>
{% endblock %}
{% sw_extends '@Storefront/storefront/component/pagination.html.twig '%}
{# All information that was previously on the radio input, is now also on the anchor link. The id attribute is longer needed. The "disabled" state is now controlled via the parent `<li>` and tabindex. #}
{% block component_pagination_first_link_element %}
<a href="{{ href ? '?p=1' ~ searchQuery : '#' }}"
class="page-link some-special-class"
data-page="1"
aria-label="{{ 'general.first'|trans|striptags }}"
data-focus-id="first"
{% if currentPage == 1 %} tabindex="-1" aria-disabled="true"{% endif %}>
{# Using text instead of icon and add some special CSS class #}
First
</a>
{% endblock %}
Some functionality changed in a way that might be noticeable for merchants. Additionally, this means that changes over the administration (e.g. adjusting configured flows, mail templates) might be needed to adjust to the new behavior.
Detailed Changes
Vat Ids will now be checked for case sensitivity, which means that most Vat Ids will now have to be upper case, depending on their validation pattern. For customers without a company, this check will only be done on entry, so it is still possible to checkout with an existing lower case Vat Id. For customers with a company, this check will be done at checkout, so they will need to change their Vat Id to upper case.
Custom field names and field set names will be validated to not contain hyphens or dots, they must be valid Twig variable names (https://github.com/twigphp/Twig/blob/21df1ad7824ced2abcbd33863f04c6636674481f/src/Lexer.php#L46). Existing custom fields continue to work, however the validation will be enforced on new custom fields.
The deprecated properties customerId
, customerNumber
, customerEmail
, customerFirstName
, customerLastName
, customerCompany
and customerSalutationId
of CustomerDeleteEvent
will be removed and cannot be accessed anymore in a mail template when sending a mail via the Checkout > Customer > Deleted
flow trigger.
- Removed condition
customerDefaultPaymentMethod
from rule builder, since customers do not have default payment methods anymore - Existing rules with this condition will be automatically migrated to the new condition
paymentMethod
, so the currently selected payment method
- Removed trigger
checkout.customer.changed-payment-method
from flow builder, since customers do not have default payment methods anymore - Existing flows will be automatically disabled with Shopware 6.7 and removed in a future, destructive migration
The default payment method "Direct debit" will no longer automatically change the order state to "in progress". Use the flow builder instead, if you want the same behavior.
The technicalName
property will be required for payment and shipping methods in the API.
The technical_name
column will be made non-nullable for the payment_method
and shipping_method
tables in the database.
Plugin developers will be required to supply a technicalName
for their payment and shipping methods.
Merchants must review their custom created payment and shipping methods for the new technicalName
property and update their methods through the administration accordingly.
We made some breaks in the API, which might affect your plugins or custom integrations.
Detailed Changes
Due to an upgrade of the "league/oauth2-server" library, some requests that are not spec-compliant with the OAuth spec are not supported anymore.
Especially scopes now needed to be provided as scope
parameter and as a space-delimited list of strings.
grant_type: 'password',
client_id: 'administration',
- scopes: ['write', 'admin'],
+ scope: 'write admin',
username: user,
password: pass,
Removed API route /api/oauth/authorize
(\Core\Framework\Api\Controller\AuthController::authorize
method) without replacement.
We made some changes in the PHP core, which might affect your plugins.
Detailed Changes
All PHP class properties now have a native type. If you have extended classes with properties, which didn't have a native type before, make sure you now add them as well.
The customer entity does not have all associations loaded by default anymore. This change reduces the amount of data loaded in the Store-API Register Route and Register related events to improve the performance.
In the following event, the CustomerEntity has no association loaded anymore:
\Shopware\Core\Checkout\Customer\Event\CustomerRegisterEvent
\Shopware\Core\Checkout\Customer\Event\CustomerRegisterEvent
\Shopware\Core\Checkout\Customer\Event\CustomerLoginEvent
\Shopware\Core\Checkout\Customer\Event\DoubleOptInGuestOrderEvent
\Shopware\Core\Checkout\Customer\Event\CustomerDoubleOptInRegistrationEvent
- The payment handlers have been reworked to provide a more flexible and consistent way to handle payments.
- The new AbstractPaymentHandler class should be used to implement payment handlers. A supports method now determines whether the recurring and refund methods can be used for a specific payment method. All other methods are invoked during every payment process, though your payment handler may not need to implement all of them.
- The following interfaces have been deprecated and consolidated into the new
AbstractPaymentHandler
:AsyncPaymentHandlerInterface
PreparedPaymentHandlerInterface
SyncPaymentHandlerInterface
RefundPaymentHandlerInterface
RecurringPaymentHandlerInterface
- Synchronous and asynchronous payments have been unified to return an optional redirect response. This response defines whether the customer is redirected to a payment provider or immediately returned to the order completion page.
- Payment handlers from plugins now receive only the
orderTransactionId
, request information (if applicable, e.g., not for recurring payments), and aContext
. Any additional data required to process the payment must be retrieved by the payment handler itself to reduce database load. This also minimises dependency on theSalesChannelContext
, which may contain information that does not accurately reflect the order (e.g., customer addresses may differ from the order’s addresses). For apps, the same information as before is still sent to the app server.
- The method
capture
has been removed from thePreparedPaymentHandler
interface. This method is no longer being called for apps. - Use the
pay
method instead for capturing previously validated payments.
The technicalName
property will be required for payment and shipping methods in the API.
The technical_name
column will be made non-nullable for the payment_method
and shipping_method
tables in the database.
Plugin developers will be required to supply a technicalName
for their payment and shipping methods.
Merchants must review their custom created payment and shipping methods for the new technicalName
property and update their methods through the administration accordingly.
- Removed default payment method from customer entity, since it was mostly overriden by old saved contexts
- Logic is now more consistent to always be the last used payment method
If the mapping definition of a many-to-many association does not contain foreign key fields, an exception will be thrown.
Elasticsearch: Return type of AbstractElasticsearchDefinition::buildTermQuery changed to BuilderInterface
The return type of \Shopware\Elasticsearch\Framework\AbstractElasticsearchDefinition::buildTermQuery()
and \Shopware\Elasticsearch\Product\AbstractProductSearchQueryBuilder::build()
changed from BoolQuery to BuilderInterface.
It is not necessary to wrap the return value in a BoolQuery anymore.
Before:
public function buildTermQuery(Context $context, Criteria $criteria): BuilderInterface
{
$built = $this->searchLogic->build($this->getEntityDefinition()->getEntityName(), $criteria, $context);
if ($built instanceof BoolQuery) {
return $built;
}
return new BoolQuery([BoolQuery::SHOULD => $built]);
}
After:
public function buildTermQuery(Context $context, Criteria $criteria): BuilderInterface
{
return $this->searchLogic->build($this->getEntityDefinition()->getEntityName(), $criteria, $context);
}
- Parameter name
column
of\Shopware\Core\Framework\Migration\MigrationStep::dropColumnIfExists
changed tocolumnName
- Parameter name
column
of\Shopware\Core\Framework\Migration\MigrationStep::dropForeignKeyIfExists
changed toforeignKeyName
- Parameter name
index
of\Shopware\Core\Framework\Migration\MigrationStep::dropIndexIfExists
changed toindexName
Changed the return type of the Shopware\Core\Checkout\Promotion\Gateway\PromotionGatewayInterface
from EntityCollection<PromotionEntity>
to PromotionCollection
- Added a new optional parameter
bool $useBatchImport
toImportExportFactory::create
. If you extend theImportExportFactory
class, you should properly handle the new parameter in your custom implementation. - Removed method
ImportExportProfileEntity::getName()
andImportExportProfileEntity::setName()
. UsegetTechnicalName()
andsetTechnicalName()
instead. - Removed
profile
attribute fromImportEntityCommand
. Use--profile-technical-name
instead. - Removed
name
field fromImportExportProfileEntity
.
We added a new optional parameter string $domainId
to SitemapHandleFactoryInterface::create
and SitemapHandleFactory::create
.
If you implement the SitemapHandleFactoryInterface
or extend the SitemapHandleFactory
class, you should properly handle the new parameter in your custom implementation.
Removed \Core\Framework\Api\Controller\AuthController::authorize
method (API route /api/oauth/authorize
) without replacement.
We added a new optional parameter bool $recursive
to TreeUpdater::batchUpdate
.
If you extend the TreeUpdater
class, you should properly handle the new parameter in your custom implementation.
<?php
class CustomTreeUpdater extends TreeUpdater
{
public function batchUpdate(array $updateIds, string $entity, Context $context, bool $recursive = false): void
{
parent::batchUpdate($updateIds, $entity, $context, $recursive);
}
}
\Shopware\Core\Framework\DataAbstractionLayer\Command\CreateSchemaCommand
will be removed. You can use \Shopware\Core\Framework\DataAbstractionLayer\Command\CreateMigrationCommand
instead.
\Shopware\Core\Framework\DataAbstractionLayer\SchemaGenerator
will be removed. You can use \Shopware\Core\Framework\DataAbstractionLayer\MigrationQueryGenerator
instead.
The Shopware\Core\Checkout\Customer\SalesChannel\AccountService::login
method is removed. Use AccountService::loginByCredentials
or AccountService::loginById
instead.
Unused constant Shopware\Core\Checkout\Customer\CustomerException::CUSTOMER_IS_INACTIVE
and unused method Shopware\Core\Checkout\Customer\CustomerException::inactiveCustomer
are removed.
floatMatch
and arrayMatch
methods in src/Core/Framework/Rule/CustomFieldRule.php
will be removed for Shopware 6.7.0.0
The Shopware\Core\Checkout\Cart\SalesChannel\AbstractCartOrderRoute::order
method will change its signature in the next major version. A new mandatory request
parameter will be introduced.
- Removed constants
Shopware\Core\Content\MailTemplate\Subscriber\MailSendSubscriberConfig::{ACTION_NAME,MAIL_CONFIG_EXTENSION}
useShopware\Core\Content\Flow\Dispatching\Action\SendMailAction::{ACTION_NAME,MAIL_CONFIG_EXTENSION}
instead - Removed constant
Shopware\Core\Content\MailTemplate\MailTemplateActions::MAIL_TEMPLATE_MAIL_SEND_ACTION
useShopware\Core\Content\Flow\Dispatching\Action\SendMailAction::ACTION_NAME
instead - Removed class
Shopware\Core\Content\MailTemplate\MailTemplateActions
without replacement - Removed service
Shopware\Core\Content\MailTemplate\Service\AttachmentLoader
without replacement. - Removed event
Shopware\Core\Content\MailTemplate\Service\Event\AttachmentLoaderCriteriaEvent
without replacement.
- Removed constants
Shopware\Core\Framework\Adapter\Cache\Http\CacheResponseSubscriber::{STATE_LOGGED_IN,STATE_CART_FILLED}
useShopware\Core\Framework\Adapter\Cache\CacheStateSubscriber::{STATE_LOGGED_IN,STATE_CART_FILLED}
instead - Removed constants
Shopware\Core\Framework\Adapter\Cache\Http\CacheResponseSubscriber::{CURRENCY_COOKIE,CONTEXT_CACHE_COOKIE,SYSTEM_STATE_COOKIE,INVALIDATION_STATES_HEADER}
useShopware\Core\Framework\Adapter\Cache\Http\HttpCacheKeyGenerator::{CURRENCY_COOKIE,CONTEXT_CACHE_COOKIE,SYSTEM_STATE_COOKIE,INVALIDATION_STATES_HEADER}
instead
We have changed/removed some exception classes in accordance with the domain exception handling ADR.
See the detailed list
- Removed
\Shopware\Core\System\SystemConfig\Exception\ConfigurationNotFoundException
. Use\Shopware\Core\System\SystemConfig\SystemConfigException::configurationNotFound
instead. - Removed
Shopware\Core\System\Snippet\Exception\FilterNotFoundException
. UseShopware\Core\System\Snippet\SnippetException::filterNotFound
instead. - Removed
Shopware\Core\System\Snippet\Exception\InvalidSnippetFileException
. UseShopware\Core\System\Snippet\SnippetException::invalidSnippetFile
instead.
Changed the InvalidArgumentException
, which was thrown in TranslationsSerializer::serialize
and TranslationsSerializer::deserialize
when the given association field wasn't a TranslationsAssociationField
, to the new ImportExportException::invalidInstanceType
exception.
Deprecated method \Shopware\Core\Content\ImportExport\ImportExportException::invalidInstanceType
. Thrown exception will change from InvalidArgumentException
to ImportExportException
.
The method \Shopware\Core\Framework\DataAbstractionLayer\DefinitionValidator::getNotices
was removed.
The following exceptions were removed:
\Shopware\Core\Framework\Api\Exception\UnsupportedEncoderInputException
\Shopware\Core\Framework\DataAbstractionLayer\Exception\CanNotFindParentStorageFieldException
\Shopware\Core\Framework\DataAbstractionLayer\Exception\InternalFieldAccessNotAllowedException
\Shopware\Core\Framework\DataAbstractionLayer\Exception\InvalidParentAssociationException
\Shopware\Core\Framework\DataAbstractionLayer\Exception\ParentFieldNotFoundException
\Shopware\Core\Framework\DataAbstractionLayer\Exception\PrimaryKeyNotProvidedException
The following methods of the \Shopware\Core\Framework\DataAbstractionLayer\Entity
class are now throwing different exceptions:
\Shopware\Core\Framework\DataAbstractionLayer\Entity::__get
now throws a\Shopware\Core\Framework\DataAbstractionLayer\DataAbstractionLayerException
instead of a\Shopware\Core\Framework\DataAbstractionLayer\Exception\InternalFieldAccessNotAllowedException
.\Shopware\Core\Framework\DataAbstractionLayer\Entity::get
now throws a\Shopware\Core\Framework\DataAbstractionLayer\DataAbstractionLayerException
instead of a\Shopware\Core\Framework\DataAbstractionLayer\Exception\InternalFieldAccessNotAllowedException
.\Shopware\Core\Framework\DataAbstractionLayer\Entity::checkIfPropertyAccessIsAllowed
now throws a\Shopware\Core\Framework\DataAbstractionLayer\DataAbstractionLayerException
instead of a\Shopware\Core\Framework\DataAbstractionLayer\Exception\InternalFieldAccessNotAllowedException
.\Shopware\Core\Framework\DataAbstractionLayer\Entity::get
now throws a\Shopware\Core\Framework\DataAbstractionLayer\Exception\PropertyNotFoundException
instead of a\InvalidArgumentException
.
We have made attribute classes final.
See the detailed list
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\AllowEmptyString
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\AllowHtml
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\AutoIncrement
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\CustomFields
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\ForeignKey
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\Inherited
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\ManyToMany
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\ManyToOne
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\OneToMany
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\OneToOne
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\PrimaryKey
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\Protection
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\ReferenceVersion
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\Required
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\Serialized
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\State
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\Translations
\Shopware\Core\Framework\DataAbstractionLayer\Attribute\Version
\Shopware\Core\Framework\Event\IsFlowEventAware
We made some changes in the administration, which might affect your plugins.
Detailed Changes
- Removed
calculationRule
association inshippingMethodCriteria()
insw-settings-shipping-detail
. - Removed
conditions
association inruleFilterCriteria()
andshippingRuleFilterCriteria()
insw-settings-shipping-price-matrix
The component sw-dashboard-statistics
(src/module/sw-dashboard/component/sw-dashboard-statistics
) has been removed without replacement.
The associated component sections sw-chart-card__before
and sw-chart-card__after
were removed, too.
Use sw-dashboard__before-content
and sw-dashboard__after-content
instead.
Before:
import { ui } from '@shopware-ag/meteor-admin-sdk';
ui.componentSection.add({
positionId: 'sw-chart-card__before',
...
})
After:
import { ui } from '@shopware-ag/meteor-admin-sdk';
ui.componentSection.add({
positionId: 'sw-dashboard__before-content',
...
})
Additionally, the associated data sets sw-dashboard-detail__todayOrderData
and sw-dashboard-detail__statisticDateRanges
were removed.
In both cases, use the Admin API instead.
Replace isEmailUsed
with isEmailAlreadyInUse
in sw-users-permission-user-detail
.
We switched the usage of basic components from custom components to the meteor component library. For more details take a look at the according ADR.
More information about how you can automate the update with codemods
will be available soon.
In short this means we replaced the following components:
sw-popover
withmt-floating-ui
sw-tabs
withmt-tabs
sw-select-field
withmt-select
sw-textarea-field
withmt-textarea
sw-datepicker
withmt-datepicker
sw-password-field
withmt-password-field
sw-colorpicker
withmt-colorpicker
sw-external-link
withmt-external-link
sw-skeleton-bar
withmt-skeleton-bar
sw-email-field
withmt-email-field
sw-url-field
withmt-url-field
sw-progress-bar
withmt-progress-bar
sw-button
withmt-button
sw-icon
withmt-icon
sw-card
withmt-card
sw-text-field
withmt-text-field
sw-switch-field
withmt-switch
sw-number-field
withmt-number-field
sw-loader
withmt-loader
sw-checkbox-field
withmt-checkbox
See the detailed list
The old "sw-popover" component will be removed in the next major version. Please use the new "mt-floating-ui" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-floating-ui" component. This component is much different from the old "sw-popover" component, so the codemod will not be able to convert all occurrences. You will have to manually adjust some parts of your codebase. For this you can look at the Storybook documentation for the Meteor Component Library.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-popover" with "mt-floating-ui".
Following changes are necessary:
Replace all component names from "sw-popover" with "mt-floating-ui"
Before:
<sw-popover />
After:
<mt-floating-ui />
The property "zIndex" is removed without a replacement.
Before:
<sw-popover :zIndex="myZIndex" />
After:
<mt-floating-ui />
The property "resizeWidth" is removed without a replacement.
Before:
<sw-popover :resizeWidth="myWidth" />
After:
<mt-floating-ui />
The property "popoverClass" is removed without a replacement.
Before:
<sw-popover popoverClass="my-class" />
After:
<mt-floating-ui />
The "open" property is removed. You have to control the visibility of the popover by yourself with the property "isOpened".
Before:
<sw-popover />
After:
<mt-floating-ui :isOpened="myVisibility" />
The old "sw-tabs" component will be removed in the next major version. Please use the new "mt-tabs" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-tabs" component. In this specific component it cannot convert anything correctly, because the new "mt-tabs" component has a different API. You have to manually check and solve every "TODO" comment created by the codemod.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-tabs" with "mt-tabs".
Following changes are necessary:
Replace all component names from "sw-tabs" with "mt-tabs"
Before:
<sw-tabs />
After:
<mt-tabs />
You need to replace the "default" slot with the "items" property. The "items" property is an array of objects which are used to render the tabs. Using the "sw-tabs-item" component is not needed anymore.
Before:
<sw-tabs>
<template #default="{ active }">
<sw-tabs-item name="tab1">Tab 1</sw-tabs-item>
<sw-tabs-item name="tab2">Tab 2</sw-tabs-item>
</template>
</sw-tabs>
After:
<mt-tabs :items="[
{
'label': 'Tab 1',
'name': 'tab1'
},
{
'label': 'Tab 2',
'name': 'tab2'
}
]">
</mt-tabs>
The content slot is not supported anymore. You need to set the content manually outside the component. You can use the "new-item-active" event to get the active item and set it to a variable. Then you can use this variable anywere in your template.
Before:
<sw-tabs>
<template #content="{ active }">
The current active item is {{ active }}
</template>
</sw-tabs>
After:
<!-- setActiveItem need to be defined -->
<mt-tabs @new-item-active="setActiveItem"></mt-tabs>
The current active item is {{ activeItem }}
Before:
<sw-tabs is-vertical />
After:
<mt-tabs vertical />
Before:
<sw-tabs align-right />
After:
<mt-tabs />
The old "sw-select-field" component will be removed in the next major version. Please use the new "mt-select" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-select" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-select-field" with "mt-select".
Following changes are necessary:
Replace all component names from "sw-select-field" with "mt-select"
Before:
<sw-select-field />
After:
<mt-select />
Replace all occurrences of the prop "value" with "modelValue"
Before:
<sw-select-field :value="selectedValue" />
After:
<mt-select :modelValue="selectedValue" />
Replace all occurrences of the "v-model:value" directive with "v-model"
Before:
<sw-select-field v-model:value="selectedValue" />
After:
<mt-select v-model="selectedValue" />
The prop "options" now expects an array of objects with the properties "label" and "value". The old format with "name" and "id" is not supported anymore.
Before:
<sw-select-field :options="[ { name: 'Option 1', id: 1 }, { name: 'Option 2', id: 2 } ]" />
After:
<mt-select :options="[ { label: 'Option 1', value: 1 }, { label: 'Option 2', value: 2 } ]" />
The prop "aside" was removed without replacement.
Before:
<sw-select-field :aside="true" />
After:
<mt-select />
The default slot was removed. The options are now passed via the "options" prop.
Before:
<sw-select-field>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</sw-select-field>
After:
<mt-select :options="[ { label: 'Option 1', value: 1 }, { label: 'Option 2', value: 2 } ]" />
The label slot was removed. The label is now passed via the "label" prop.
Before:
<sw-select-field>
<template #label>
My Label
</template>
</sw-select-field>
After:
<mt-select label="My Label" />
The event "update:value" was renamed to "update:modelValue"
Before:
<sw-select-field @update:value="onUpdateValue" />
After:
<mt-select @update:modelValue="onUpdateValue" />
The old "sw-textarea-field" component will be removed in the next major version. Please use the new "mt-textarea" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-textarea" component. In this specific component it cannot convert anything correctly, because the new "mt-textarea" component has a different API. You have to manually check and solve every "TODO" comment created by the codemod.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-textarea-field" with "mt-textarea".
Following changes are necessary:
Replace all component names from "sw-textarea-field" with "mt-textarea"
Before:
<sw-textarea-field />
After:
<mt-textarea />
Replace all occurrences of the property "value" with "modelValue"
Before:
<sw-textarea-field :value="myValue" />
After:
<mt-textarea :modelValue="myValue" />
Replace all occurrences of the binding "v-model:value" with "v-model"
Before:
<sw-textarea-field v-model:value="myValue" />
After:
<mt-textarea v-model="myValue" />
Replace all occurrences of the slot "label" with the property "label"
Before:
<sw-textarea-field>
<template #label>
My Label
</template>
</sw-textarea-field>
After:
<mt-textarea label="My Label" />
Replace all occurrences of the event "update:value" with "update:modelValue"
Before:
<sw-textarea-field @update:value="onUpdateValue" />
After:
<mt-textarea @update:modelValue="onUpdateValue" />
The old "sw-datepicker" component will be removed in the next major version. Please use the new "mt-datepicker" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-datepicker" component. In this specific component it cannot convert anything correctly, because the new "mt-datepicker" component has a different API. You have to manually check and solve every "TODO" comment created by the codemod.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-datepicker" with "mt-datepicker".
Following changes are necessary:
Replace all component names from "sw-datepicker" with "mt-datepicker"
Before:
<sw-datepicker />
After:
<mt-datepicker />
Replace all occurrences of the property "value" with "modelValue"
Before:
<sw-datepicker :value="myValue" />
After:
<mt-datepicker :modelValue="myValue" />
Replace all occurrences of the binding "v-model:value" with "v-model"
Before:
<sw-datepicker v-model:value="myValue" />
After:
<mt-datepicker v-model="myValue" />
Replace all occurrences of the slot "label" with the property "label"
Before:
<sw-datepicker>
<template #label>
My Label
</template>
</sw-datepicker>
After:
<mt-datepicker label="My Label" />
Replace all occurrences of the event "update:value" with "update:modelValue"
Before:
<sw-datepicker @update:value="onUpdateValue" />
After:
<mt-datepicker @update:modelValue="onUpdateValue" />
The old "sw-password-field" component will be removed in the next major version. Please use the new "mt-password-field" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-password-field" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-password-field" with "mt-password-field".
Following changes are necessary:
Replace all component names from "sw-password-field" with "mt-password-field"
Before:
<sw-password-field>Hello World</sw-password-field>
After:
<mt-password-field>Hello World</mt-password-field>
Replace all occurrences of the "value" prop with "modelValue"
Before:
<sw-password-field value="Hello World" />
After:
<mt-password-field modelValue="Hello World" />
Replace all occurrences of the "v-model:value" directive with "v-model"
Before:
<sw-password-field v-model:value="myValue" />
After:
<mt-password-field v-model="myValue" />
Replace all occurrences of the "size" prop with "default"
Before:
<sw-password-field size="medium" />
After:
<mt-password-field size="default" />
Remove all occurrences of the "isInvalid" prop
Before:
<sw-password-field isInvalid />
After:
<mt-password-field />
Replace all occurrences of the "update:value" event with "update:modelValue"
Before:
<sw-password-field @update:value="updateValue" />
After:
<mt-password-field @update:modelValue="updateValue" />
Remove all occurrences of the "base-field-mounted" event
Before:
<sw-password-field @base-field-mounted="onFieldMounted" />
After:
<mt-password-field />
Remove all occurrences of the "label" slot. The slot content should be moved to the "label" prop. Only string values are supported. Other slot content is not supported anymore.
Before:
<sw-password-field>
<template #label>
My Label
</template>
</sw-password-field>
After:
<mt-password-field label="My label">
</mt-password-field>
Remove all occurrences of the "hint" slot. The slot content should be moved to the "hint" prop. Only string values are supported. Other slot content is not supported
Before:
<sw-password-field>
<template #hint>
My Hint
</template>
</sw-password-field>
After:
<mt-password-field hint="My hint">
</mt-password-field>
The old "sw-colorpicker" component will be removed in the next major version. Please use the new "mt-colorpicker" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-colorpicker" component. In this specific component it cannot convert anything correctly, because the new "mt-colorpicker" component has a different API. You have to manually check and solve every "TODO" comment created by the codemod.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-colorpicker" with "mt-colorpicker".
Following changes are necessary:
Replace all component names from "sw-colorpicker" with "mt-colorpicker"
Before:
<sw-colorpicker />
After:
<mt-colorpicker />
Replace all occurrences of the property "value" with "modelValue"
Before:
<sw-colorpicker :value="myValue" />
After:
<mt-colorpicker :modelValue="myValue" />
Replace all occurrences of the binding "v-model:value" with "v-model"
Before:
<sw-colorpicker v-model:value="myValue" />
After:
<mt-colorpicker v-model="myValue" />
Replace all occurrences of the slot "label" with the property "label"
Before:
<sw-colorpicker>
<template #label>
My Label
</template>
</sw-colorpicker>
After:
<mt-colorpicker label="My Label" />
Replace all occurrences of the event "update:value" with "update:modelValue"
Before:
<sw-colorpicker @update:value="onUpdateValue" />
After:
<mt-colorpicker @update:modelValue="onUpdateValue" />
The old "sw-external-link" component will be removed in the next major version. Please use the new "mt-external-link" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-external-link" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-external-link" with "mt-external-link".
Following changes are necessary:
Replace all component names from "sw-external-link" with "mt-external-link"
Before:
<sw-external-link>Hello World</sw-external-link>
After:
<mt-external-link>Hello World</mt-external-link>
The "icon" property is removed from the "mt-external-link" component. There is no replacement for this property.
Before:
<sw-external-link icon="world">Hello World</sw-external-link>
After:
<mt-external-link>Hello World</mt-external-link>
The old "sw-skeleton-bar" component will be removed in the next major version. Please use the new "mt-skeleton-bar" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-skeleton-bar" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-skeleton-bar" with "mt-skeleton-bar".
Following changes are necessary:
Replace all component names from "sw-skeleton-bar" with "mt-skeleton-bar"
Before:
<sw-skeleton-bar>Hello World</sw-skeleton-bar>
After:
<mt-skeleton-bar>Hello World</mt-skeleton-bar>
The old "sw-email-field" component will be removed in the next major version. Please use the new "mt-email-field" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-email-field" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-email-field" with "mt-email-field".
Following changes are necessary:
Replace all component names from "sw-email-field" with "mt-email-field"
Before:
<sw-email-field>Hello World</sw-email-field>
After:
<mt-email-field>Hello World</mt-email-field>
Replace all occurrences of the "value" prop with "modelValue"
Before:
<mt-email-field value="Hello World" />
After:
<mt-email-field modelValue="Hello World" />
Replace all occurrences of the "v-model:value" directive with "v-model"
Before:
<mt-email-field v-model:value="myValue" />
After:
<mt-email-field v-model="myValue" />
Replace all occurrences of the "size" prop with "default"
Before:
<mt-email-field size="medium" />
After:
<mt-email-field size="default" />
Remove all occurrences of the "isInvalid" prop
Before:
<mt-email-field isInvalid />
After:
<mt-email-field />
Remove all occurrences of the "aiBadge" prop
Before:
<mt-email-field aiBadge />
After:
<mt-email-field />
Replace all occurrences of the "update:value" event with "update:modelValue"
Before:
<mt-email-field @update:value="updateValue" />
After:
<mt-email-field @update:modelValue="updateValue" />
Remove all occurrences of the "base-field-mounted" event
Before:
<mt-email-field @base-field-mounted="onFieldMounted" />
After:
<mt-email-field />
Remove all occurrences of the "label" slot. The slot content should be moved to the "label" prop. Only string values are supported. Other slot content is not supported anymore.
Before:
<mt-email-field>
<template #label>
My Label
</template>
</mt-email-field>
After:
<mt-email-field label="My label">
</mt-email-field>
The old "sw-url-field" component will be removed in the next major version. Please use the new "mt-url-field" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-url-field" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-url-field" with "mt-url-field".
Following changes are necessary:
Replace all component names from "sw-url-field" with "mt-url-field"
Before:
<sw-url-field />
After:
<mt-url-field />
Replace all occurrences of the "value" prop with "modelValue"
Before:
<sw-url-field value="Hello World" />
After:
<mt-url-field modelValue="Hello World" />
Replace all occurrences of the "v-model:value" directive with "v-model"
Before:
<sw-url-field v-model:value="myValue" />
After:
<mt-url-field v-model="myValue" />
Replace all occurrences of the "update:value" event with "update:modelValue"
Before:
<sw-url-field @update:value="updateValue" />
After:
<mt-url-field @update:modelValue="updateValue" />
Remove all occurrences of the "label" slot. The slot content should be moved to the "label" prop. Only string values are supported. Other slot content is not supported anymore.
Before:
<sw-url-field>
<template #label>
My Label
</template>
</sw-url-field>
After:
<mt-url-field label="My label">
</mt-url-field>
Remove all occurrences of the "hint" slot. There is no replacement for this slot.
Before:
<sw-url-field>
<template #hint>
My Hint
</template>
</sw-url-field>
After:
<mt-url-field />
The old "sw-progress-bar" component will be removed in the next major version. Please use the new "mt-progress-bar" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-progress-bar" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-progress-bar" with "mt-progress-bar".
Following changes are necessary:
Replace all component names from "sw-progress-bar" with "mt-progress-bar"
Before:
<sw-progress-bar />
After:
<mt-progress-bar />
Replace all occurrences of the "value" prop with "modelValue"
Before:
<mt-progress-bar value="5" />
After:
<mt-progress-bar modelValue="5" />
Replace all occurrences of the "v-model:value" directive with "v-model"
Before:
<mt-progress-bar v-model:value="myValue" />
After:
<mt-progress-bar v-model="myValue" />
Replace all occurrences of the "update:value" event with "update:modelValue"
Before:
<mt-progress-bar @update:value="updateValue" />
After:
<mt-progress-bar @update:modelValue="updateValue" />
The old "sw-button" component will be removed in the next major version. Please use the new "mt-button" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-button" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-button" with "mt-button".
Following changes are necessary:
Replace all component names from "sw-button" with "mt-button"
Before:
<sw-button>Save</sw-button>
After:
<mt-button>Save</mt-button>
Remove the property "variant". Use the property "ghost" instead.
Before:
<sw-button variant="ghost">Save</sw-button>
After:
<mt-button ghost>Save</mt-button>
Replace the value "danger" with "critical" in the property "variant".
Before:
<sw-button variant="danger">Delete</sw-button>
After:
<mt-button variant="critical">Delete</mt-button>
Replace the value "ghost-danger" with "critical" in the property "variant". Add the property "ghost".
Before:
<sw-button variant="ghost-danger">Delete</sw-button>
After:
<mt-button variant="critical" ghost>Delete</mt-button>
Remove the value "contrast" from the property "variant". There is no replacement.
Remove the value "context" from the property "variant". There is no replacement.
Replace the property "router-link" with a "@click" event listener and a "this.$router.push()" method.
Before:
<sw-button router-link="sw.example.route">Go to example</sw-button>
After:
<mt-button @click="this.$router.push('sw.example.route')">Go to example</mt-button>
The old "sw-icon" component will be removed in the next major version. Please use the new "mt-icon" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-icon" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-icon" with "mt-icon".
Following changes are necessary:
Replace all component names from "sw-icon" with "mt-icon"
Before:
<sw-icon name="regular-times-s" />
After:
<mt-icon name="regular-times-s" />
Replace the property "small" with "size" of value "16px" if used
Before:
<sw-icon name="regular-times-s" small />
After:
<mt-icon name="regular-times-s" size="16px" />
Replace the property "large" with "size" of value "32px" if used
Before:
<sw-icon name="regular-times-s" large />
After:
<mt-icon name="regular-times-s" size="32px" />
If no property "size", "small" or "large" is used, you need to use the "size" prop with the value "24px" to avoid a different default size than with "sw-icon"
Before:
<sw-icon name="regular-times-s" />
After:
<mt-icon name="regular-times-s" size="24px" />
The old "sw-card" component will be removed in the next major version. Please use the new "mt-card" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-card" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-card" with "mt-card".
Following changes are necessary:
Replace all component names from "sw-card" with "mt-card"
Before:
<sw-card>Hello World</sw-card>
After:
<mt-card>Hello World</mt-card>
Replace the property "aiBadge" by using the "sw-ai-copilot-badge" component directly inside the "title" slot
Before:
<mt-card aiBadge>Hello Wolrd</mt-card>
After:
<mt-card>
<slot name="title"><sw-ai-copilot-badge /></slot>
Hello World
</mt-card>
The property "contentPadding" is removed without a replacement.
Before:
<mt-card contentPadding>Hello World</mt-card>
After:
<mt-card>Hello World</mt-card>
The old "sw-text-field" component will be removed in the next major version. Please use the new "mt-text-field" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-text-field" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-text-field" with "mt-text-field".
Following changes are necessary:
Replace all component names from "sw-text-field" with "mt-text-field"
Before:
<sw-text-field>Hello World</sw-text-field>
After:
<mt-text-field>Hello World</mt-text-field>
Replace all occurrences of the "value" prop with "modelValue"
Before:
<mt-text-field value="Hello World" />
After:
<mt-text-field modelValue="Hello World" />
Replace all occurrences of the "v-model:value" directive with "v-model"
Before:
<mt-text-field v-model:value="myValue" />
After:
<mt-text-field v-model="myValue" />
Replace all occurrences of the "size" prop with "default"
Before:
<mt-text-field size="medium" />
After:
<mt-text-field size="default" />
Remove all occurrences of the "isInvalid" prop
Before:
<mt-text-field isInvalid />
After:
<mt-text-field />
Remove all occurrences of the "aiBadge" prop
Before:
<mt-text-field aiBadge />
After:
<mt-text-field />
Replace all occurrences of the "update:value" event with "update:modelValue"
Before:
<mt-text-field @update:value="updateValue" />
After:
<mt-text-field @update:modelValue="updateValue" />
Remove all occurrences of the "base-field-mounted" event
Before:
<mt-text-field @base-field-mounted="onFieldMounted" />
After:
<mt-text-field />
Remove all occurrences of the "label" slot. The slot content should be moved to the "label" prop. Only string values are supported. Other slot content is not supported anymore.
Before:
<mt-text-field>
<template #label>
My Label
</template>
</mt-text-field>
After:
<mt-text-field label="My label">
</mt-text-field>
The old "sw-switch-field" component will be removed in the next major version. Please use the new "mt-switch" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-switch" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-switch-field" with "mt-switch".
Following changes are necessary:
Replace all component names from "sw-switch-field" with "mt-switch".
Before:
<sw-switch-field>Hello World</sw-switch-field>
After:
<mt-switch>Hello World</mt-switch>
Replace all occurrences of the "noMarginTop" prop with "removeTopMargin".
Before:
<mt-switch noMarginTop />
After:
<mt-switch removeTopMargin />
Remove all occurrences of the "size" prop.
Before:
<mt-switch size="small" />
After:
<mt-switch />
Remove all occurrences of the "id" prop.
Before:
<mt-switch id="example-identifier" />
After:
<mt-switch />
Replace all occurrences of the "value" prop with "checked".
Before:
<mt-switch value="true" />
After:
<mt-switch checked="true" />
Remove all occurrences of the "ghostValue" prop.
Before:
<mt-switch ghostValue="true" />
After:
<mt-switch />
Remove all occurrences of the "padded" prop. Use CSS styling instead.
Before:
<mt-switch padded="true" />
After:
<mt-switch />
Remove all occurrences of the "partlyChecked" prop.
Before:
<mt-switch partlyChecked="true" />
After:
<mt-switch />
Replace all occurrences of the "label" slot with the "label" prop.
Before:
<mt-switch>
<template #label>
Foobar
</template>
</mt-switch>
After:
<mt-switch label="Foobar">
</mt-switch>
Remove all occurrences of the "hint" slot.
Before:
<mt-switch>
<template #hint>
Foobar
</template>
</mt-switch>
After:
<mt-switch>
<!-- Slot "hint" was removed with no replacement. -->
</mt-switch>
The old "sw-number-field" component will be removed in the next major version. Please use the new "mt-number-field" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-number-field" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-number-field" with "mt-number-field".
Following changes are necessary:
Replace all component names from "sw-number-field" with "mt-number-field"
Before:
<sw-number-field />
After:
<mt-number-field />
Replace all occurrences of the "value" prop with "modelValue"
Before:
<mt-number-field :value="5" />
After:
<mt-number-field :modelValue="5" />
Replace all occurrences of the "v-model:value" directive with the combination of :modelValue
and @change
Before:
<mt-number-field v-model:value="myValue" />
After:
<mt-number-field :modelValue="myValue" @change="myValue = $event" />
Replace all occurrences of the "label" slot with the "label" prop
Before:
<mt-number-field>
<template #label>
My Label
</template>
</mt-number-field>
After:
<mt-number-field label="My Label" />
Replace all occurrences of the "update:value" event with the "change" event
Before:
<mt-number-field @update:value="updateValue" />
After:
<mt-number-field @change="updateValue" />
The old "sw-loader" component will be removed in the next major version. Please use the new "mt-loader" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-loader" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-loader" with "mt-loader".
Following changes are necessary:
Replace all component names from "sw-loader" with "mt-loader"
Before:
<sw-loader />
After:
<mt-loader />
The old "sw-checkbox-field" component will be removed in the next major version. Please use the new "mt-checkbox" component instead.
We will provide you with a codemod (ESLint rule) to automatically convert your codebase to use the new "mt-checkbox" component.
If you don't want to use the codemod, you can manually replace all occurrences of "sw-checkbox-field" with "mt-checkbox".
Following changes are necessary:
Replace all component names from "sw-checkbox-field" with "mt-checkbox"
Before:
<sw-checkbox-field />
After:
<mt-checkbox />
Replace all occurrences of the "value" prop with "checked"
Before:
<sw-checkbox-field :value="myValue" />
After:
<mt-checkbox :checked="myValue" />
Replace all occurrences of the "v-model" directive with "v-model:checked"
Before:
<sw-checkbox-field v-model="isCheckedValue" />
After:
<mt-checkbox v-model:checked="isCheckedValue" />
Replace all occurrences of the "label" slot with the "label" prop
Before:
<sw-checkbox-field>
<template #label>
Hello Shopware
</template>
</sw-checkbox-field>
After:
<mt-checkbox label="Hello Shopware">
</mt-checkbox>
The "hint" slot was removed without replacement
Before:
<sw-checkbox-field>
<template v-slot:hint>
Hello Shopware
</template>
</sw-checkbox-field>
The "id" prop was removed without replacement
Before:
<sw-checkbox-field id="checkbox-id" />
The "ghostValue" prop was removed without replacement
Before:
<sw-checkbox-field ghostValue="yes" />
Replace all occurrences of the "partlyChecked" prop with "partial"
Before:
<sw-checkbox-field partlyChecked />
After:
<mt-checkbox partial />
The "padded" prop was removed without replacement
Before:
<sw-checkbox-field padded />
Replace all occurrences of the "update:value" event with "update:checked"
Before:
<sw-checkbox-field @update:value="updateValue" />
After:
<mt-checkbox @update:checked="updateValue" />
We made some changes in the Storefront, which might affect your plugins and themes.
Detailed Changes
- The properties
header
andfooter
and their getter and setter Methods in\Shopware\Storefront\Framework\Twig\ErrorTemplateStruct
were removed. - The loading of header, footer, payment methods and shipping methods in
\Shopware\Storefront\Page\GenericPageLoader
is removed. Extend\Shopware\Storefront\Pagelet\Header\HeaderPageletLoader
or\Shopware\Storefront\Pagelet\Footer\FooterPageletLoader
instead. - The properties
header
,footer
,salesChannelShippingMethods
andsalesChannelPaymentMethods
and their getter and setter Methods in\Shopware\Storefront\Page\Page
were removed. Extend\Shopware\Storefront\Pagelet\Header\HeaderPagelet
or\Shopware\Storefront\Pagelet\Footer\FooterPagelet
instead. - The property
serviceMenu
and its getter and setter Methods in\Shopware\Storefront\Pagelet\Header\HeaderPagelet
were removed. Extend it via the\Shopware\Storefront\Pagelet\Footer\FooterPagelet
instead. - The
navigationId
request parameter in\Shopware\Storefront\Pagelet\Header\HeaderPageletLoader::load
was removed. - The
setNavigation
method in\Shopware\Storefront\Pagelet\Menu\Offcanvas\MenuOffcanvasPagelet
was removed. - The option
tiggerEvent
inOffcanvasMenuPlugin
JavaScript plugin was removed, usetriggerEvent
instead. - The following blocks were moved from
src/Storefront/Resources/views/storefront/base.html.twig
tosrc/Storefront/Resources/views/storefront/layout/header.html.twig
.base_header
base_header_inner
base_navigation
base_navigation_inner
base_offcanvas_navigation
base_offcanvas_navigation_inner
- The following blocks were moved from
src/Storefront/Resources/views/storefront/base.html.twig
tosrc/Storefront/Resources/views/storefront/layout/footer.html.twig
.base_footer
base_footer_inner
- The template variable
page
in following templates was removed. Provideheader
orfooter
directly.src/Storefront/Resources/views/storefront/layout/footer/footer.html.twig
src/Storefront/Resources/views/storefront/layout/header/actions/currency-widget.html.twig
src/Storefront/Resources/views/storefront/layout/header/actions/language-widget.html.twig
src/Storefront/Resources/views/storefront/layout/header/top-bar.html.twig
src/Storefront/Resources/views/storefront/layout/navbar/navbar.html.twig
- The template variables
activeId
andactivePath
insrc/Storefront/Resources/views/storefront/layout/navbar/categories.html.twig
were removed. - The template variable
activePath
insrc/Storefront/Resources/views/storefront/layout/navbar/navbar.html.twig
was removed. - The parameter
activeResult
ofsrc/Storefront/Resources/views/storefront/layout/sidebar/category-navigation.html.twig
was removed.
Both \Shopware\Storefront\Theme\ThemeFileImporterInterface
& \Shopware\Storefront\Theme\ThemeFileImporter
are removed without replacement. These classes are already not used as of v6.6.5.0 and therefore this extension point is removed with no planned replacement.
getBasePath
& setBasePath
methods and basePath
property on StorefrontPluginConfiguration
are removed. If you need to get the absolute path you should ask for a filesystem instance via \Shopware\Storefront\Theme\ThemeFilesystemResolver::getFilesystemForStorefrontConfig()
passing in the config object.
This filesystem instance can read files via a relative path and also return the absolute path of a file. Eg:
$fs = $this->themeFilesystemResolver->getFilesystemForStorefrontConfig($storefrontPluginConfig);
foreach($storefrontPluginConfig->getAssetPaths() as $relativePath) {
$absolutePath = $fs->path('Resources', $relativePath);
}
- The service
\Shopware\Storefront\Page\Product\Review\ProductReviewLoader
was removed. Use\Shopware\Core\Content\Product\SalesChannel\Review\AbstractProductReviewLoader
instead. - The event
\Shopware\Storefront\Page\Product\Review\ProductReviewsLoadedEvent
was removed. Use\Shopware\Core\Content\Product\SalesChannel\Review\Event\ProductReviewsLoadedEvent
instead. - The hook
\Shopware\Storefront\Page\Product\Review\ProductReviewsWidgetLoadedHook
was removed. Use\Shopware\Core\Content\Product\SalesChannel\Review\ProductReviewsWidgetLoadedHook
instead. - The struct
\Shopware\Storefront\Page\Product\Review\ReviewLoaderResult
was removed. Use\Shopware\Core\Content\Product\SalesChannel\Review\ProductReviewResult
instead.
The mixin sw-skin-alert
will be removed in v6.7.0. Instead of styling the alert manually with CSS selectors and the custom mixin sw-skin-alert
,
we modify the appearance inside the alert-*
modifier classes directly with the Bootstrap CSS variables like it is documented: https://getbootstrap.com/docs/5.3/components/alerts/#sass-loops
Before:
@each $color, $value in $theme-colors {
.alert-#{$color} {
@include sw-skin-alert($value, $white);
}
}
After:
@each $state, $value in $theme-colors {
.alert-#{$state} {
--#{$prefix}alert-border-color: #{$value};
--#{$prefix}alert-bg: #{$white};
--#{$prefix}alert-color: #{$body-color};
}
}
When rendering an alert using the include template Resources/views/storefront/utilities/alert.html.twig
, the class alert-has-icon
will be removed. Helper classes d-flex align-items-center
will be used instead.
- <div class="alert alert-info alert-has-icon">
+ <div class="alert alert-info d-flex align-items-center">
{% sw_icon 'info' %}
<div class="alert-content-container">
An important info
</div>
</div>
As of v6.7.0, the superfluous inner container alert-content
will be removed to have lesser elements and be more aligned with Bootstraps alert structure.
When rendering an alert using the include template Resources/views/storefront/utilities/alert.html.twig
, the inner container alert-content
will no longer be present in the HTML output.
The general usage of Resources/views/storefront/utilities/alert.html.twig
and all include parameters remain the same.
Before:
<div role="alert" class="alert alert-info d-flex align-items-center">
<span class="icon icon-info"><svg></svg></span>
<div class="alert-content-container">
<div class="alert-content">
Your shopping cart is empty.
</div>
</div>
</div>
After:
<div role="alert" class="alert alert-info d-flex align-items-center">
<span class="icon icon-info"><svg></svg></span>
<div class="alert-content-container">
Your shopping cart is empty.
</div>
</div>
With v6.7.0, the supported browsers in the .browserslist
file will be updated to defaults
. This is a recommended setting including browsers with >0.5%
global usage statistic.
This saves JS bundle size because polyfills for older browser like Chrome 60 or Firefox 60 are no longer included and the native implementation can be used instead.
If you want to restore the previous browser support in your project or want to adjust it, you can use environment variable BROWSERSLIST
in your .env
.
# Adjust .browserslist for JS build process
BROWSERSLIST='>= 0.5%, last 2 major versions, not dead, Chrome >= 60, Firefox >= 60, Firefox ESR, iOS >= 12, Safari >= 12, not Explorer <= 11'
With v6.7.0 we upgrade the following NPM packages to their newest major version.
The upgrades are done for packages related to the webpack JS-build process and do not require changes to the source code.
If you are customizing the webpack config inside <plugin root>/src/Resources/app/storefront/build/webpack.config.js
, please consolidate the changelogs of the affected packages.
- Upgrade
copy-webpack-plugin
from11.0.0
to12.0.2
- Upgrade
css-loader
from6.8.1
to7.1.2
- Upgrade
postcss-loader
from7.3.4
to8.1.1
- Upgrade
sass-loader
from13.3.3
to16.0.4
- Upgrade
style-loader
from3.3.3
to4.0.0
- Upgrade
webpack-cli
from5.1.4
to6.0.1
- Upgrade
webpack-merge
from5.10.0
to6.0.1
- Upgrade
webpackbar
from6.0.0
to7.0.0
- Upgrade
webpack-dev-server
from4.15.1
to5.2.0
With v6.7.0 the following NPM packages will be removed.
Creating a query string from object:
Before:
import queryString from 'query-string';
const paramsString = queryString.stringify({ key: 'value', elementId: 'some-id' })
After:
const paramsString = new URLSearchParams({ key: 'value', elementId: 'some-id' }).toString();
Creating an object from queryString:
Before:
import queryString from 'query-string';
const paramsObj = querystring.parse(window.location.search);
After:
const paramsObj = Object.fromEntries(new URLSearchParams(window.location.search).entries());
New functions: sw_block
, sw_source
, sw_include
and new tokens: sw_use
, sw_embed
, sw_from
and sw_import
.
You can find further details on the use on the documentation page Shopware's twig functions.
We made some changes in the app-system, which might affect your apps.
Detailed Changes
The version of the manifest XSD file increased.
Consider validating your manifest.xml
against src/Core/Framework/App/Manifest/Schema/manifest-3.0.xsd
now.
With this change we removed the capture-url
element from the payment-method
type.
Implement the pay-url
instead.
For asynchronous payments, the default payment state unconfirmed
was used for the pay
call and paid
for finalized
. This is no longer the case. Payment states are no longer set by default.
The finalize
step now transmits the queryParameters
under the object key requestData
as other payment calls
The onlyAvailable
flag in the Shopware\Core\Checkout\Gateway\SalesChannel\CheckoutGatewayRoute
in the request is removed. The route always filters the payment and shipping methods before calling the checkout gateway based on availability.
We made some changes in the configuration and setup, which might affect your project setups.
Detailed Changes
The XKeys module is now required for Varnish. If you are using Varnish, you need to ensure that the XKeys module is installed and enabled. Storing the cache tags for varnish inside redis is not possible anymore, as that solution let to serious scaling issues where the redis tag storage become the bottleneck.
For more information take a look inside the docs.
This means that the following configuration keys are no longer available:
shopware.http_cache.reverse_proxy.use_varnish_xkey
shopware.http_cache.reverse_proxy.redis_url
Next configuration keys are deprecated and will be removed in the next major version:
shopware.cache.invalidation.delay_options.dsn
shopware.increment.<increment_name>.config.url
shopware.number_range.redis_url
shopware.number_range.config.dsn
shopware.cart.redis_url
cart.storage.config.dsn
To prepare for migration:
- For all different redis connections (different DSNs) that are used in the project, add a separate record in the
config/packages/shopware.yaml
file under theshopware
section, as in upgrade section of this document. - Replace deprecated dsn/url keys with corresponding connection names in the configuration files.
shopware.cache.invalidation.delay_options.dsn
->shopware.cache.invalidation.delay_options.connection
shopware.increment.<increment_name>.config.url
->shopware.increment.<increment_name>.config.connection
shopware.number_range.redis_url
->shopware.number_range.config.connection
shopware.number_range.config.dsn
->shopware.number_range.config.connection
shopware.cart.redis_url
->cart.storage.config.connection
cart.storage.config.dsn
->cart.storage.config.connection
The services bundle now needs to be enabled explicitly in your config/bundles.php
, to do that add the following line:
$bundles = [
...
Shopware\Elasticsearch\Elasticsearch::class => ['all' => true],
+ Shopware\Core\Service\Service::class => ['all' => true],
];
When you use a symfony flex setup it should pick up the change automatically and apply that change during the shopware update.
Previously we had a default configuration of three shards and three replicas. With 6.7 we removed this default configuration and now the search server is responsible for providing the correct configuration. This allows that the indices automatically scale based on your nodes available in the cluster.
You can revert to the old behavior by setting the following configuration in your config/packages/shopware.yml
:
elasticsearch:
index_settings:
number_of_shards: 3
number_of_replicas: 3
Any message queue message bigger than 256KB will be now rejected by default. To reduce the size of your messages you should only store the ID of an entity in the message and fetch it later in the message handler. This can be disabled again with:
shopware:
messenger:
enforce_message_size: false
The fine-grained caching mechanism for system-config, snippets and theme config was removed, therefore the following configuration settings are no longer available:
shopware.cache.tagging.each_config
shopware.cache.tagging.each_snippet
shopware.cache.tagging.each_theme_config
Removed SQL_SET_DEFAULT_SESSION_VARIABLES
env variable. It has no effect anymore.
The previously optional performance tweaks to MySQL are now enforced on connection buildup inside the \Shopware\Core\Framework\Adapter\Database\MySQLFactory
.