Migration Guides
This area contains the Migration steps to follow for upgrading your store to new Front-Commerce versions.
To update Front-Commerce in your project, use the command below (with the exact version you need):
npm install git+ssh://git@gitlab.blackswift.cloud/front-commerce/front-commerce.git#2.33.0
2.33.0
-> 2.34.0
β
Google Consent V2 Supportβ
In this release, we've added support for Google's Consent Mode v2 which provides more granular control over user consent preferences. This change affects applications using either the Google Analytics 4 or Google Tag Manager plugins.
To enable this feature, add the
consentOptions
to your service configuration in cookiesServices.js
You can also take advantage of the consentOptions
in your custom plugins by
following the
Granular Consent Updates
guide.
If you have overriden any of these files, please make sure you apply the changes to your overrides:
- theme/modules/Cookie/CookieLink/CookieLink.js
- theme/modules/Cookie/CookieModal/CookieModal.js
- theme/modules/Cookie/CookiePage/CookieGrid/CookieGrid.js
- theme/modules/Cookie/CookiePage/CookieLine/CookieLine.js
- theme/modules/Cookie/CookiePage/CookieLine/_CookieLine.scss
- theme/modules/Cookie/CookiePage/CookiePage.js
2.32.0
-> 2.33.0
β
No manual migration steps are required for this release.
2.31.0
-> 2.32.0
β
No manual migration steps are required for this release.
2.30.0
-> 2.31.0
β
No manual migration steps are required for this release.
2.29.0
-> 2.30.0
β
Fixed add to wishlist after new registrationβ
In this version we fixed the add to wishlist state updates after the first registration. Previously it would not display a product in the wishlist until a full page reload is initiated.
To accommodate this fix, we had to add changes to the following files;
- src/web/theme/modules/Wishlist/AddProductToWishlist/withIsProductInWishlist.js
- src/web/theme/modules/Wishlist/AddProductToWishlist/withProductWishlistMutations.js
If you have overridden these files please ensure to update them with the changes.
Reworked QuickOrder componentβ
In this version, we've introduced a new feature that enables you to bulk import products from a CSV file and directly add them to your cart.
The Quick order page is active by default at /quick-order
. If you want to
opt-out of this feature, you will have to remove the route
using the front-commerce-prepare.js::onCreateRoute
callback.
To develop this new feature, we've had to update the following files;
src/web/theme/modules/ProductPicker/ProductPicker.js
src/web/theme/modules/AddToCart/AddToCartModal/AddToCartModalQuery.gql
src/web/theme/modules/QuickOrder/QuickOrder.js
- https://gitlab.blackswift.cloud/front-commerce/front-commerce/-/commit/f2efb127286d4f17a5fb6d48d23fb32c0418e9be#a72de350cd94321d5b8db2bb90e500f068bb09c5
- https://gitlab.blackswift.cloud/front-commerce/front-commerce/-/commit/8171a6fde0aac903f3d4852466df072840ca3015#a72de350cd94321d5b8db2bb90e500f068bb09c5
src/web/theme/modules/QuickOrder/_QuickOrder.scss
Stripe integration now uses IPNs on Magento2 / Magento2 B2Bβ
In this version we've updated Stripe payment module to use IPNs. To cope with this change, you will need to ensure that:
- Stripe is configured to use an
asyncOrder
checkout flow
diff --git a/src/web/theme/pages/Checkout/checkoutFlowOf.js b/src/web/theme/pages/Checkout/checkoutFlowOf.js
index f7bd3222f..b843608da 100644
--- a/src/web/theme/pages/Checkout/checkoutFlowOf.js
+++ b/src/web/theme/pages/Checkout/checkoutFlowOf.js
@@ -11,6 +11,7 @@ const checkoutFlowOf = (method) => {
if (method.startsWith("hipay_")) return "directOrderWithAdditionalAction";
if (method === "payzen_embedded") return "asyncOrder";
+ if (method === "stripe") return "asyncOrder";
return "directOrder";
};
- In
StripeCheckout
component,cartId
is added to thepaymentData
object in the checkout state:
diff --git a/src/web/theme/modules/Checkout/Payment/AdditionalPaymentInformation/StripeCheckout/StripeCheckout.js b/src/web/theme/modules/Checkout/Payment/AdditionalPaymentInformation/StripeCheckout/StripeCheckout.js
index 5539c0c87..976f89594 100644
--- a/src/web/theme/modules/Checkout/Payment/AdditionalPaymentInformation/StripeCheckout/StripeCheckout.js
+++ b/src/web/theme/modules/Checkout/Payment/AdditionalPaymentInformation/StripeCheckout/StripeCheckout.js
@@ -41,6 +41,7 @@ const withData = compose(
loading: data.loading,
clientSecret:
!data.loading && data.cart?.stripe?.paymentIntent?.clientSecret,
+ cartId: !data.loading && data.cart?.id,
}),
})
),
@@ -101,6 +102,7 @@ const StripeCheckoutComponent = (props) => {
} else if (paymentIntent.status === "requires_capture") {
const paymentData = {
paymentIntentId: paymentIntent.id,
+ cartId: props.cartId,
};
setState({
loading: false,
Fixed multiple triggers of "Order Completed" analytics eventβ
In this version we've fixed the issue where the "Order Completed" event would be
triggered multiple times by refreshing the /checkout/success
page (see
related commit).
To benefit from this fix, you will need to ensure that the following changes have been applied to your project, in the case you overrode those files:
diff --git a/src/web/theme/modules/Checkout/withCheckoutTracking/withCheckoutSuccessTracking.js b/src/web/theme/modules/Checkout/
withCheckoutTracking/withCheckoutSuccessTracking.js
index 1f1cc1cd1..8fe9f3d61 100644
--- a/src/web/theme/modules/Checkout/withCheckoutTracking/withCheckoutSuccessTracking.js
+++ b/src/web/theme/modules/Checkout/withCheckoutTracking/withCheckoutSuccessTracking.js
@@ -6,6 +6,10 @@ import trackEvent from "theme/modules/Analytics/trackEvent";
import CheckoutSuccessTrackingQuery from "./CheckoutSuccessTrackingQuery.gql";
const trackCartOrdered = (order) => {
+ const shouldTrack = localStorage.getItem("trackOrderCompleted");
+ if (!shouldTrack) {
+ return;
+ }
try {
const formatItemForAnalytics = ({ sku, name, row_total, qty_ordered }) => ({
sku,
@@ -25,6 +29,7 @@ const trackCartOrdered = (order) => {
discount: order.totals.discount.value.amount,
products: order.items.map(formatItemForAnalytics),
});
+ localStorage.removeItem("trackOrderCompleted");
} catch (e) {
console.error(
"Failed to send successfull order to tracking. Does it have a valid format?"
diff --git a/src/web/theme/pages/Checkout/stepsDefinition.js b/src/web/theme/pages/Checkout/stepsDefinition.js
index d54db0f25..6d40d9ac4 100644
--- a/src/web/theme/pages/Checkout/stepsDefinition.js
+++ b/src/web/theme/pages/Checkout/stepsDefinition.js
@@ -170,17 +170,20 @@ const steps = [
isDisplayable: (checkoutState) => !!checkoutState.paymentMethod,
},
{
- renderStep: (props) => (
- <Redirect
- to={{
- pathname: "/checkout/success",
- state: {
- ...props.checkoutState.placedOrderData,
- checkoutState: props.checkoutState,
- },
- }}
- />
- ),
+ renderStep: (props) => {
+ localStorage.setItem("trackOrderCompleted", "true");
+ return (
+ <Redirect
+ to={{
+ pathname: "/checkout/success",
+ state: {
+ ...props.checkoutState.placedOrderData,
+ checkoutState: props.checkoutState,
+ },
+ }}
+ />
+ );
+ },
isValid: (checkoutState) => false,
isRelevant: () => true,
isDisplayable: (checkoutState) => checkoutState.isPlaced,
New features in 2.30.0
β
2.28.0
-> 2.29.0
β
No manual migration steps are required for this release.
2.27.0
-> 2.28.0
β
No manual migration steps are required for this release.
2.26.0
-> 2.27.0
β
Magento1: Reviewsβ
In this release, we added the ability to see and publish product reviews for Magento1. However, you will need to update your Front-Commerce Magento1 module to version 1.6.0 or above for this feature to work.
New features in 2.27.0
β
- An optimized implementation of
addMultipleItemsToCart
mutation for Magento2 - Review support for Magento1
2.25.0
-> 2.26.0
β
Requisition List UID Updateβ
In version 2.26.0, we have updated the behavior of the requisition list UID to align with the Magento 2 GraphQL API.
The requisition list UID is now a base64-encoded string instead of a decoded string value.
If you are using a Magento version lower than 2.4.5, you must update the requisition list module by running the following command:
composer require magento/module-requisition-list-graph-ql 1.3.3
We have added the
FRONT_COMMERCE_MAGENTO_UNSAFE_LEGACY_REQUISITION_LIST_ID=true
environment
variable for backward compatibility. However, please note that this variable
will be removed in version 3.0. To ensure future compatibility, we recommend
updating the Magento module instead of relying on this environment variable.
Configurable Axios Timeoutsβ
In this version, we have added the ability to configure the timeouts for the Axios instance used by Front-Commerce. We recommend using the new configuration instead of the timeout file with static values, which has been marked as deprecated for v3.0.
The loaders that previously used these values have been updated to use a
configProvider
to get the values, which are customizable via the following
environment variables:
- Magento1 configProvider
FRONT_COMMERCE_MAGENTO_TIMEOUT
(default: 60000)FRONT_COMMERCE_MAGENTO_ADMIN_TIMEOUT
(default: 10000)
- Magento2 configProvider
FRONT_COMMERCE_MAGENTO_TIMEOUT
(default: 60000)FRONT_COMMERCE_MAGENTO_ADMIN_TIMEOUT
(default: 10000)
- Colissimo configProvider
FRONT_COMMERCE_COLISSIMO_TIMEOUT
(default: 10000)
- Ogone configuration
FRONT_COMMERCE_OGONE_TIMEOUT
(default: 10000)
We hope this documentation helps you configure the timeouts for the Axios instance used by Front-Commerce. If you have any questions or concerns, please don't hesitate to contact us.
Redis invalidation SCAN iterations size configuration (invalidationScanIterationSize
)β
We've increased the default iterations size for SCAN
commands issued by the
Redis caching strategy
during cache invalidation with wildcards.
It used to be an arbitrary value of 100, and we increased it to 1000 to have better performances when invalidating cache on databases containing several millions of keys.
We feel it's a better default from our observations. This value is now
configurable, so if you want to tweak its value or go back to the previous
behavior, please update your caching.js
with the
invalidationScanIterationSize: 100
value.
New features in 2.26.0
β
- caching: the
PerMagentoCustomerTaxZone
caching strategy is now also available for Magento 1, to cache prices per tax zone (see documentation) - payment: Authorize.net is now supported for Magento1 (OpenMage LTS)
projects. To use it, please update the Magento module
front-commerce/magento1-module
to 1.5.0+
2.24.0
-> 2.25.0
β
Updated canonical URL creation methodβ
Breaking: In this version we have changed the way
QueryHelper.filterCanonicalQueryStringParameters
compute the canonical URL
parameters, in order to better fit SEO-recommended rules (see
Google article
on this matter).
To opt-in to this behaviour, you can pass a boolean as the second parameter of
QueryHelper.filterCanonicalQueryStringParameters
to configure whether or not
additional filters should be included in the canonical. true
(default value)
will include additional filters, and false
will exclude them. Please note that
we removed the sorting
, minPrice
and maxPrice
parameters from the
canonical url parameters.
See more in the related commit.
Drop support of Node 14β
In this version we've dropped support for Node 14 (EOL: 2023-04-30). The minimum required version is now Node 16.
You need to check your project dependencies for compatibility with at least Node
16 (you can check npm to find infos about your
dependencies) and upgrade them in your package.json
file.
If you are a Front-Commerce-Cloud customer, when you upgrade to Front-Commerce 2.25+, please contact us to upgrade the Node version used to deploy your project(s).
New default sorting method for ElasticSearch datasourceβ
In this version we changed the behavior when sorting with ElasticSearch datasource. From now on, if no sorting params are passed to the datasource, it will instead sort by the items' category index.
It also affects the sort by "Popular" on Front-Commerce themes.
Please let us know if you encounter any issues regarding this new behavior.
Use facet labels as valuesβ
To opt-in to using facet labels as values, you must add the following following
configuration to your config/website
:
module.exports = {
...
search: {
dynamicFacetSize: 10,
ignoredAttributeKeys: [],
attributeFacetMinimumDocumentCount: 1,
authorizedCategoriesFacet: [],
categoryFacetMinimumDocumentCount: 1,
useAttributeLabels: true,
},
};
This also introduced the new isUsingIdsForAttributes
method for datasources,
if you have custom datasources, you must implement this method.
If your datasource already uses labels as values the method should return
false
, for example:
- Algolia uses labels as values
- Elasticsearch uses ids as values
Multi shipment enhanced displayβ
Only for Magento 2
In this version we've added the list of products shipped in each shipments of an order.
If you've redefined the resolver for Shipment.trackingDetails
, you must
synchronize your version to apply
the same kind of change as in the patch providing the feature
so that items
is correctly defined in the tracking details.
If you've overridden the OrderShipmentTrackingFragment.gql
file, you must
inject a new fragment:
#import "theme/modules/User/Order/OrderShipmentTrackingProducts/OrderShipmentTrackingProductsFragment.gql"
fragment OrderShipmentTrackingFragment on Shipment {
trackingDetails {
trackingId
name
url
items {
...OrderShipmentTrackingProductsFragment
}
__typename
}
}
If you've overridden the BaseTrackingDetails
component, you must add a new
component to display the list of items:
import React from "react";
import { FormattedMessage } from "react-intl";
import Link from "theme/components/atoms/Typography/Link";
import { BodyFade } from "theme/components/atoms/Typography/Body";
import OrderShipmentTrackingProducts from "theme/modules/User/Order/OrderShipmentTrackingProducts";
const Tracking = ({ tracking }) => {
const name = tracking.url ? (
<Link to={tracking.url}>{tracking.name}</Link>
) : (
tracking.name
);
return (
<div className="account-orders-details__item">
<div className="account-orders-details__item__title">{name}</div>
<BodyFade>
<FormattedMessage
id="modules.User.Order.OrderShipmentTracking.number"
defaultMessage="Tracking number: {trackingId}"
values={{ trackingId: tracking.trackingId }}
/>
</BodyFade>
<OrderShipmentTrackingProducts items={tracking.items} />
</div>
);
};
export default Tracking;
Magic Buttonβ
To implement the Magic Button related features, we have changed several files from the theme:
theme/layouts/GenericLayout.js
(see the corresponding commit)theme/modules/ProductView/ProductItem/ProductItem.js
(see the corresponding commit)theme/modules/CmsBlock/CmsBlock.js
(see the corresponding commit)theme/pages/Product/Product.js
(see the corresponding commit)theme/pages/Account/Dashboard/Dashboard.js
(see the corresponding commit)theme/pages/Account/Dashboard/EnhanceDashboard.js
(see the corresponding commit)theme/pages/Account/Orders/Details/Invoice/Invoice.js
(see the corresponding commit)theme/pages/Account/Orders/Details/Details.js
(see the corresponding commit)theme/pages/CmsPage/CmsPage.js
(see the corresponding commit)theme/pages/Category/Category.js
(see the corresponding commit)- Mandatory
theme/components/atoms/Colors/_colors.scss
(see the corresponding commit) theme/modules/_modules.scss
(see this first commit and this second commit)theme/components/_components.scss
(see the corresponding changes)
If you have an override of template/index.html
, you need to apply the
following changes:
<script>
window.__APOLLO_STATE__ = %%__APOLLO_STATE__%%;
</script>
+ <script>
+ window.__CONTRIBUTION_MODE_DATA__ = %%__CONTRIBUTION_MODE_DATA__%%;
+ </script>
<script>
window.__MAINTENANCE__ = %%__MAINTENANCE__%%;
</script>
We strongly advice you to synchronize any override you may have done in your project.
Negotiable Quotes: online paymentsβ
In this release, we've added support for a first online payment method (Stripe) to the negotiable quote checkout.
To achieve this feature, we had to perform a minor but potentially impactful Breaking Change to the negotiable checkout. The payment method selection step now only performs a single mutation instead of two.
The setNegotiableQuotePaymentMethod
and placeNegotiableQuoteOrder
mutations
have been merged into setNegotiableQuotePaymentInformationAndPlaceOrder
. Here
is
the merge request containing the diff,
so that you can check whether or not your overrides are affected by this change.
To use this feature you need to:
- update your Magento2 B2B Front-Commerce module to version 1.2.0+
- ensure you haven't overriden theme files impacted with this breaking change
Impacted files:
theme/modules/Checkout/NegotiableQuotes/Payment/ChoosePayment.js
theme/modules/Checkout/NegotiableQuotes/Payment/EnhanceChoosePayment.js
theme/modules/Checkout/NegotiableQuotes/Payment/SetNegotiableQuotePaymentMethod.gql
theme/modules/Checkout/NegotiableQuotes/PlaceOrder/EnhancePlaceOrder.js
theme/modules/Checkout/NegotiableQuotes/PlaceOrder/PlaceNegotiableQuoteOrderMutation.gql
theme/modules/Checkout/NegotiableQuotes/PlaceOrder/PlaceOrder.js
theme/modules/Checkout/NegotiableQuotes/PlaceOrder/SetNegotiableQuotePaymentInformationAndPlaceOrderMutation.gql
We usually try hard to avoid Breaking Changes. In this context, we decided to remain pragmatic as we knew that this relatively new feature wasn't used by many projects. For this reason, we chose the simplest solution instead of adding complexity with deprecated GraphQL mutations and conditional paths in the checkout. Please contact us if you need help with this upgrade.
Image cachingβ
In this version we've introduced
Focal Point
support for the <Image>
component.
If you use Front-Commerce's media middleware, the cache needs to be fully regenerated.
To do so, you should delete the .front-commerce/cache/images
directory and
deploy your project.
Regenerate image cache will lead to a high CPU usage, to not disturb the availability of your app, we recommend you do this outside peak visit time on your website.
Performance: remove chunks preloadingβ
We've
removed the chunks preloading feature
as it led to blocking network requests that could reduce the LCP / FCP
of your app. From our analysis it improves the performance of the application and is a good default.
We invite you to test the impact of this change (i.e: run a Core Web Vitals test on your application and compare the results to confirm this).
If you want to restore the previous behavior, you can set the
FRONT_COMMERCE_ENABLE_CHUNKS_PRELOAD=true
environment variable.
New features in 2.25.0
β
2.23.0
-> 2.24.0
β
We've released version 2.24.1 which fixes a critical regression introduced in version 2.24.0. Please ensure that you're upgrading to the latest 2.24.x version.
Apple Pay and Google Pay support with Stripeβ
In this version, we have added support for Apple Pay and Google Pay with Stripe. We have also took this as an opportunity to upgrade Stripe related dependencies. If your project uses Stripe, we strongly advice you to test your integration.
To enable support for Apple Pay and Google Pay, we have
changed the implementation of StripeCheckoutForm
to use Stripe's PaymentElement
instead of Stripe's CardElement
.
This results in a slight user interface change. Please update your
theme/modules/Checkout/Payment/AdditionalPaymentInformation/StripeCheckout/*
overrides if any.
ImageAdapters without multiple sourcesβ
In the version we extended the ImageAdapters
feature allow an adapter to
change how sources are generated for the srcSet, to allow this, we had to
make changes to the makeImagesProps
If you have overriden this file, you will need to update it to match the new
implementation.
import imageAdapters from "./adapters";
const makeImgProps = (baseUrl, src, format, bg, cover, fluid) => {
// [..]
const sourcesExtensions = imageAdapters.getSupportedExtensions(
src,
bg === "transparent"
);
const defaultExtension = imageAdapters.getDefaultExtension(src);
return {
src: makeImgSrc(src, format, sizes[0], bg, extension, cover, baseUrl),
src: makeImgSrc(src, format, sizes[0], bg, defaultFormat, cover, baseUrl),
sources: sourcesExtensions.map((extension) => ({
type: `image/${extension}`,
...(extension ? { type: `image/${extension}` } : {}),
srcSet: makeImageSrcset(
baseUrl,
src,
format,
sizes,
bg,
extension,
cover,
fluid
),
})),
};
};
We also added two optional methods getSupportedExtensions
and
getDefaultExtension
to adapters, see
Custom ImageAdapters documentation
for more information.
This change removed the responsibility of the
exported transparentExtensions
, extensions
and defaultExtension
consts from the ImageComponent
so we have marked them for deprecation in v3,
they are currently re-exporting the methods from the default Front-Commerce
image adapter
Search engine interface updatedβ
If you implemented a very custom search engine datasource, please update it to
expose a scopes.queries.matchingQuery
scope. You can use a dummy
implementation if you don't want to support search query autocompletion. See
MR!2072
for an example.
If you use an existing Front-Commerce search engine (Platform native, ElasticSearch, Algolia or Attraqt), you don't have anything to do.
New features in 2.24.0
β
- Apple Pay and Google Pay support with Stripe
- Added additional CSP directives.
- Akamai Image Manager adapter
for the
<Image>
component
2.22.0
-> 2.23.0
β
Adobe Commerce RMAβ
This version contains improvements to RMA functionality. When updating your
project, you must also update the
Magento2 Commerce - Module Front Commerce to version 2.1.0+
composer require front-commerce/magento2-commerce-module@2.1.0
Adobe Commerce Negotiable quotesβ
In this version, we added support for Negotiable quotes. When updating your project, if you want to be able to use Negotiable quotes, please note that you will need to synchronize your changes with the core ones on the following files:
theme/components/atoms/Icon/icons/core-icons.js
(1f324c8a)theme/modules/Cart/CartFooter.js
(a4ae74ac)theme/modules/User/AccountNavigation/AccountNavigation.js
(a4ae74ac)theme/layouts/Header/Navigation/AccountNavigation/AccountSubNavigation.js
(a4ae74ac)theme/pages/Account/AccountLayout.js
(1f324c8a)theme/_b2b.scss
(ddc9b581)
New features in 2.23.0
β
- Use Magento's
storeConfig
GraphQL query to access configurations with theMagentoGraphQLConfig
loader - Attraqt: add contextual information to your queries
2.21.0
-> 2.22.0
β
Fix sort params in QueryHelper
's getFacetsParams
β
We detected a bug related to sort
parameters retrieved from the URL (notably
on the PLP page), where the GraphQL query would fail if the object passed in
this URL parameter did not match the SortInput
input
defined in the GraphQL schema.
We fixed it by picking only the parameters required by the schema in
QueryHelper.getFacetsParams()
.
Breaking change: If you extended SortInput
input in the GraphQL schema,
you will also need to override this QueryHelper
method to reflect those
changes, otherwise only the base input fields will be taken into account.
2.20.0
-> 2.21.0
β
Algolia facet configurationsβ
As of this version, the Algolia datasource for Magento2 takes the facet type
into account to build queries sent to Algolia. In previous versions,
Front-Commerce behaved as if the facet type was set to Conjunctive
. So by
upgrading to this version, you might experience a change of behavior in the
search results. To avoid that, you can set the facet type to Conjunctive
under
Stores > Configuration > Algolia Search > Instant Search Results Page in the
Facets configuration.
Media proxy updated to send a custom user agentβ
If you have added a custom media proxy endpoint in your application, we recommend to update the code as follows:
- import proxy from "express-http-proxy";
+ import proxy from "server/core/proxy";
We detected an issue with some remote services that were blocking Front-Commerce
due to firewall rules detecting a weird behavior caused by the media proxy:
many requests from the same IP address with different User-Agent
values was
considered as a suspicious activity. It could ultimately lead to a blacklisting.
This behavior
has been fixed
in this version and backported to all support branches. Front-Commerce will now
send a custom User-Agent
value to the remote services:
Front-Commerce media proxy/<version>
(where <version>
is the version of
Front-Commerce). Please update your codebase as described above to ensure your
code is compatible with this new behavior.
2.19.0
-> 2.20.0
β
Default shipping and billing address supportβ
In this release, we updated how the "Use as default billing address"
and
"Use as default shipping address"
checkboxes are displayed in the
AddressForm
component. It now can be controlled globally using a configuration in the
src/config/website.js
configuration file.
Please check if you have overridden the AddressForm
component
(commit)
if you're interested in using this feature.
2.18.0
-> 2.19.0
β
Replaced mkdirp
package with make-dir
β
Due to
a bug
causing issues with our image resizer we have opted to replace the
mkdirp
package with
make-dir
in our dependencies,
starting from version 2.19.0
we will no longer ship this package in
Front-Commerce, so if you are using mkdirp
in your own code, you will need to
ensure that you have installed it.
npm install mkdirp@^1.0.4
Allow report-only frames for Adyenβ
If you were using Adyen as a payment provider you might have allowed all iframes to load, to prevent blocking 3DS2 authorization iframes from credit card providers.
You can now restrict the policy again and use the reportOnlyDirectives
feature
instead.
Although it will not strengthen the policy, this will allow to log loaded iframes and help investigate risks of unsecure iframes.
contentSecurityPolicy: {
directives: {
- frameSrc: ["*"],
+ frameSrc: ["*.adyen.com"],
}
+ reportOnlyDirectives: {
+ frameSrc: true,
+ }
},
Configure the new loggerβ
A new security
logger has been added (for now to collect CSP violations).
Add it to your logging.js
configuration to be able to see those logs (see
the logging documentation for
more details)
module.exports = {
...
access: [
{
type: "console",
},
],
security: [
{
...
},
],
};
Adding custom iconsβ
We have improved the way you can add custom icons to your theme. Before you had
to override the
theme/components/atoms/Icon/Icon.js
file to add your custom icons. Now you can simply extend or override the core
icons with your custom icons by adding them to the
theme/components/atoms/Icon/icons/app-icons.js
file.
import { FcHome, FcPhone } from "react-icons/fc";
/** @type {Record<string, import("react-icons").IconType>} */
const componentIcons = {
home: FcHome // this will override the `IoIosHome` icon from the core implementation
phone: FcPhone // this will add a new icon
};
/** @type {string[]} */
const svgIcons = [];
export default {
componentIcons,
svgIcons,
};
To apply this change you need to restore the original Icon.js
files, you can
do this by deleting the override from your custom theme.
Default country from graphβ
In this release, we have changed the usage of default_country_id
defined in
your stores.js
configuration.
From 2.19.0, this settings is directly exposed in the GraphQL API directly in
Country.isDefault
field.
This field will use the value returned by Magento2, and default to the one
defined in your stores.js
otherwise. In order to fully benefit from this
change, you will also have to update you Front-Commerce Magento 2 module to
version 2.9.0.
On other backends (Magento1, BigCommerce), this field will only expose the value
from your stores.js
.
Breaking changes: Previously, this setting was used directly in the frontend
in web/theme/modules/User/Address/AddressForm/AddressForm.js
, and was removed
in favor of using the isDefault
field in the graph. Please verify if you
overwrote any of these files:
web/theme/modules/User/Address/AddressForm/AddressForm.js
web/theme/modules/User/Address/CountryFieldWithRegion/CountriesWithRegionQuery.gql
web/theme/modules/User/Address/CountryFieldWithRegion/withCountriesAndRegions.js
Form/Item
inline
property depreciationβ
To standardize the API of theme/components/molecules/Form/Item
between the
default theme and the theme chocolatine, the inline
property of that component
from the default theme has been deprecated to use an appearance
property. So
if your project is not using the theme chocolatine and
theme/components/molecules/Form/Item
explicitly receives the inline
property, you have to apply changes similar to:
import FormItem from "theme/components/molecules/Form/Item";
const MyComponent = () => {
return (
- <FormItem inline={true}>
+ <FormItem appearance="inline">
<SomeComponent />
</FormItem>
);
}
or
import FormItem from "theme/components/molecules/Form/Item";
const MyComponent = () => {
return (
- <FormItem inline={false}>
+ <FormItem>
<SomeComponent />
</FormItem>
);
}
New features in 2.19.0
β
- The Stripe module can be configured to not automatically capture the payment
- Report-Only CSP are now configurable
- Magento2 performance improvements (opt-in)
- ChronoRelais shipping method support
2.17.0
-> 2.18.0
β
The Prismic module has moved to a new home.β
We have tagged the last version of the Prismic module in the
external repository
v1
π₯³
Since this version we have moved the Prismic module into the core repository of Front-Commerce, moving forward any new features will be made available and follow the same semantic versioning as the core.
You can use the module by adding the following changes to your
.front-commerce.js
config file:
module.exports = {
modules: [
"./node_modules/front-commerce/theme-chocolatine",
- "./node_modules/front-commerce-prismic/prismic",
+ "./node_modules/front-commerce/modules/prismic",
"./src",
],
serverModules: [
{ name: "FrontCommerce", path: "server/modules/front-commerce" },
{
name: "Magento2Elasticsearch",
path: "datasource-elasticsearch/server/modules/magento2-elasticsearch",
},
{ name: "Magento2", path: "server/modules/magento2" },
{ name: "Prismic", path: "prismic/server/modules/prismic" },
],
webModules: [
{ name: "FrontCommerce", path: "front-commerce/src/web" },
- {
- name: "Prismic",
- path: "./node_modules/front-commerce-prismic/prismic/web",
- },
],
};
path-to-regexp package addedβ
We noticed that the
path-to-regexp
package was
missing from our dependencies, it was only useable due to a transitive
dependency. We have added it to our dependencies to avoid any future issues.
The previous version of the package was 0.1.7
and we have upgraded it to
6.2.1
. Because of others dependencies depending on older version of
path-to-regexp
, you have to install it in your project in order to satisfy
Front-Commerce's requirements by running:
npm install path-to-regexp@^6.2.1
If you don't, you'll experience server side rendering errors like:
TypeError: Object(...) is not a function
at /path/to/your/project/build/server/webpack:/node_modules/front-commerce/src/server/modules/magento2/catalog/products/urlMatchers.js:6:1
If you used this import without installing it in your project, the import methods have changed.
- import pathToRegexp from "path-to-regexp";
+ import { pathToRegexp } from "path-to-regexp";
In addition, given the amount of changes between the version 0.1.7 and 6.2.1, we strongly advice you to check the project documentation and to carefully test any code involving this library.
Magento2 Adyen module updateβ
In this release, we added support for version 8 of Magento2 Adyen module. If you
have a Front-Commerce setup where the module Magento2/Adyen
is used,
the FRONT_COMMERCE_ADYEN_MAGENTO_MODULE_VERSION
environment variable is now required and it must contain the Magento2 module version.
New configurations were added in the Adyen Magento module regarding headless storefronts. Please ensure you've configured the "Headless Integration" as per our docs.
DomainEvent implementations reworkedβ
The PaymentDetails
attribute was removed from the payment DomainEvents. A
custom paymentData last attribute now allows your payment methods to provide
custom JSON payload to the magento backend.
- new PaymentReceived(orderId, paymentDetails, pspReference)
+ new PaymentReceived(orderId, pspReference, paymentData)
Concerned classes : PaymentAuthenticationStarted
, PaymentAuthorized
,
PaymentCaptured
, PaymentCancelled
, PaymentReceived
and PaymentRefused
FRONT_COMMERCE_WEB_UNSAFE_USE_DEPRECATED_FIELDS
support removalβ
The support for the undocumented environment variable
FRONT_COMMERCE_WEB_UNSAFE_USE_DEPRECATED_FIELDS
has been removed in this
version. If you were previously defining this variable, you can safely remove
it. The main use case for this variable was to change npm run lint
behavior so
that it triggers a warning instead of an error when a deprecated GraphQL is
used. This is now the default behavior.
New Adobe Commerce B2B PHP moduleβ
Some B2B features were previously leveraging features from the Magento2 Commerce module. During this release, we've extracted B2B related features into their own repository.
If you work on an Adobe Commerce B2B project, you must:
- update
front-commerce/magento2-commerce-module
to version 2.x (currently2.0.0
) - install
front-commerce/magento2-b2b-module
to its latest version
Here are the commands to achieve this:
composer require front-commerce/magento2-commerce-module:2.0.0
composer config repositories.front-commerce-magento2-b2b git \
git@gitlab.blackswift.cloud:front-commerce/magento2-b2b-module-front-commerce.git
composer require front-commerce/magento2-b2b-module:1.1.0
bin/magento setup:upgrade
2.16.0
-> 2.17.0
β
Adyen's Stored payment methodsβ
In this release, we added support for Adyen's Stored Payment Methods for its Magento module. For more information, see Adyen's Stored Payment Methods documentation.
Payment workflow reworkβ
We added a new frontend payment workflow for payment means using asynchronous notifications. As most embedded payment methods will be migrated in the future, please ensure you update the following files if you overrode them
...
+import AsyncOrderQuery from "./AsyncOrderQuery.gql";
...
EnhancePlaceOrder({
SetPaymentInfoAndPlaceOrderMutation,
SetCheckoutPaymentInformationAndRedirectMutation,
PlaceOrderAndRedirectMutation,
+ AsyncOrderQuery,
}),
branch(
- (props) => props.hasMessage,
+ (props) => props.message || props.errorMessage,
() => ErrorOccured,
(BaseComponent) => BaseComponent
)
...
+import withAsyncOrderAction from "./PaymentFlow/withAsyncOrderAction";
export const supportedPaymentFlowTypes = [
"directOrder",
+ "asyncOrder",
"redirectBeforeOrder",
"redirectAfterOrder",
"directOrderWithAdditionalAction",
"workflowAgnosticCheckout",
];
const EnhancePlaceOrder = ({
SetPaymentInfoAndPlaceOrderMutation,
SetCheckoutPaymentInformationAndRedirectMutation,
PlaceOrderAndRedirectMutation,
+ AsyncOrderQuery,
}) =>
...
withHandlers({
onError:
(props) =>
({ errorMessage }) =>
props.formatErrorMessage(errorMessage),
}),
+ withAsyncOrderAction(AsyncOrderQuery),
makeCommandDispatcher({
DomainEvent reworkβ
The DomainEvent class was reworked.
If you handled payment events on orders (backend operation) using
DomainEvent implementations,
these implementations now base on a PurchaseIdentifier
instead of a direct
orderId
(this allows to update order events based on a cartId)
Here is the new usage for those classes
new PaymentCaptured(
- orderId,
+ new PurchaseIdentifier({ orderId }),
paymentDetail
)
Payzen/Lyra on Magento1β
We migrated the Payzen/Lyra embedded payment module for Magento2 to the new
asyncOrder
payment workflow.
As this is not supported for Magento1, override
theme/pages/Checkout/checkoutFlowOf.js
to keep using the former workflow.
const checkoutFlowOf = (method) => {
...
- if (method === "payzen_embedded") return "asyncOrder";
+ if (method === "payzen_embedded") return "directOrder";
...
};
2.15.0
-> 2.16.0
β
Updating Front-Commerce from 2.15.0 to 2.16.0 does not require any manual operation.
2.14.0
-> 2.15.0
β
Environment variables: quote values containing #
or ``` charactersβ
As part of our continuous dependencies upgrade process, we've upgraded the
dotenv
dependency to its latest version. We've updated it from version 8.2.0
(October 2019) to version 16.0.0
(February 2022). Technically, it contains 2
Breaking Changes that we've decided to be pragmatic about.
We prioritized having an up-to-date dependency with a minor migration check, over an outdated one for pure SemVer compatibility.
Please check that your environment variables are not impacted by these breaking
changes:
- 15.0.0:
#
marks the beginning of a comment (UNLESS the value is wrapped in quotes. Please update your.env
files to wrap in quotes any values containing#
: - 16.0.0: If you had values containing the backtick character, please quote those values with either single or double quotes.
- SECRET_WITH_HASH=something-with-a-#-hash
- SECRET_WITH_BACKTICK=something-with-a-`-backtick
+ SECRET_WITH_HASH="something-with-a-#-hash"
+ SECRET_WITH_BACKTICK="something-with-a-`-backtick"
you can change your environment variables right away. Quoted values also work with previous Front-Commerce versions.
In-Stock Alertsβ
In this release, we introduced the In-Stock Alert feature. When this feature is
enabled on your backend (Magento 1 and 2), it will by default render a new
component SubscribeToInStockAlert
inside the existing OutOfStock
component.
Paginated ordersβ
In this release we added pagination for orders. In the process, the orders
GraphQL field used to retrieve orders has been deprecated and will eventually be
removed in FC version 3.0.0. orderList
should now be used instead. If you had
overridden the Orders
(theme/pages/Account/Orders/Orders.js
) component, you
might want to update it to use the new GraphQL field and add a pagination
component.
Node Version Support Changeβ
We now support Node versions 14, 16 and 17 (Node 17 is supported on a best effort basis). If you are using Node 12 (which reached its end of life), you must update your Node version (we recommend Node 16). To support these latest Node versions, we had to upgrade some dependencies. These upgrades imply changes that could impact your codebase:
-
You need to update to the latest version of your
front-commerce-skeleton
-
@apollo/*
are only installed as sub-dependencies and therefore should not be used directly. In2.15.0
you need to replace all uses of@apollo/*
in your codebase withreact-apollo
, orgraphql-tag
imports where applicable.Check if you overrode any file that you need to apply the changes to
modules/front-commerce-b2b/web/core/permissions/CompanyPermissionsContext.js- * @property {import('@apollo/react-hoc').DataValue<{ me: Object }, {}>} data
+ * @property {import('react-apollo').DataValue<{ me: Object }, {}>} datamodules/front-commerce-b2b/web/theme/modules/Company/CompanyStructure/CompanyStructure/withCompanyStructureMutations.js-import { useMutation } from "@apollo/react-hooks";
-
-/**
- * @callback MutationFunction
- * @param {import('@apollo/react-common/lib/types/types').MutationFunctionOptions} options
- * @returns {Promise<import('@apollo/react-common/lib/types/types').ExecutionResult>}
- */
+import { useMutation } from "react-apollo";
+
+/**
+ * @typedef {typeof useMutation} UseMutation
+ * @typedef {ReturnType<useMutation>} UseMutationReturn
+ * @typedef {UseMutationReturn[0]} MutationFunction
+ */modules/front-commerce-b2b/web/theme/modules/Company/CompanyUserDeactivate/CompanyUserDeactivate.js-import { useMutation } from "@apollo/react-hooks";
+import { useMutation } from "react-apollo";modules/front-commerce-b2b/web/theme/modules/Company/CompanyUserModal/CompanyUserModal.js-import { useMutation } from "@apollo/react-hooks";
+import { useMutation } from "react-apollo";modules/front-commerce-b2b/web/theme/modules/RequisitionList/AddToRequisitionList/withAddMultipleItemsToNewRequisitionListMutation.js- * @returns {Promise<import('@apollo/react-common/lib/types/types').ExecutionResult>}
modules/front-commerce-b2b/web/theme/modules/RequisitionList/AddToRequisitionList/withAddMultipleItemsToRequisitionListMutation.js+/**
+ * @typedef {typeof useMutation} UseMutation
+ * @typedef {ReturnType<useMutation>} UseMutationReturn
+ * @typedef {UseMutationReturn[0]} MutationFunction
+ * @typedef {ReturnType<MutationFunction>} MutationFunctionReturn
+ */
/**
* @typedef {object} AddToRequisitionListFunctionProps
* @param {string} requisitionListId
* @param {any[]} selectedItems
*/
/**
* @callback AddToRequisitionListFunction
* @param {AddToRequisitionListFunctionProps} props
- * @returns {Promise<import('@apollo/react-common/lib/types/types').ExecutionResult>}
+ * @returns {MutationFunctionReturn}
*/modules/front-commerce-b2b/web/theme/modules/RequisitionList/AddToRequisitionList/withProductConfigurationModal.js- * @returns {Promise<import('@apollo/react-common/lib/types/types').ExecutionResult>}
modules/front-commerce-b2b/web/theme/modules/RequisitionList/RequisitionListDelete/RequisitionListDelete.js-import { useMutation } from "@apollo/react-hooks";
+import { useMutation } from "react-apollo";modules/front-commerce-b2b/web/theme/modules/RequisitionList/RequisitionListItemsGrid/RequisitionListItem/RequisitionListItem.js-import { useMutation } from "@apollo/react-hooks";
+import { useMutation } from "react-apollo";modules/front-commerce-b2b/web/theme/modules/RequisitionList/RequisitionListModal/RequisitionListCreateModal/RequisitionListCreateModal.js-import { useMutation } from "@apollo/react-hooks";
+import { useMutation } from "react-apollo";modules/front-commerce-b2b/web/theme/modules/RequisitionList/RequisitionListModal/RequisitionListUpdateModal/RequisitionListUpdateModal.js-import { useMutation } from "@apollo/react-hooks";
+import { useMutation } from "react-apollo";modules/front-commerce-b2b/web/theme/modules/RequisitionList/RequisitionListToolbar/RequisitionListToolbarAddToCart/RequisitionListToolbarAddToCart.js-import { useMutation } from "@apollo/react-hooks";
+import { useMutation } from "react-apollo";modules/front-commerce-b2b/web/theme/pages/Account/CompanyStructure/EnhanceCompanyStructure.js- * @param {import('@apollo/react-hoc/lib/types').OptionProps<any, GraphQLData, any>} param0
+ * @param {import('react-apollo').OptionProps<any, GraphQLData, any>} param0modules/front-commerce-b2b/web/theme/pages/Account/RequisitionListDetails/EnhanceRequisitionListDetails.js- * @param {import('@apollo/react-hoc/lib/types').OptionProps<any, GraphQLData, any>} param0
+ * @param {import('react-apollo').OptionProps<any, GraphQLData, any>} param0modules/payment-adyen/web/theme/modules/Adyen/PaypalCheckout/EnhancePaypalCheckout.js- * @param {import('@apollo/react-hoc/lib/types').OptionProps<any, GraphQLData, any>} param0
+ * @param {import('react-apollo').OptionProps<any, GraphQLData, any>} param0modules/payment-adyen/web/theme/modules/Checkout/PlaceOrder/AdditionalAction/Adyen/Adyen.js-import { useQuery } from "@apollo/react-hooks";
+import { useQuery } from "react-apollo";modules/payment-hipay/web/theme/modules/Checkout/PlaceOrder/AdditionalAction/HiPay/HiPayActions.js-import { useQuery } from "@apollo/react-hooks";
+import { useQuery } from "react-apollo";src/web/core/apollo/graphqlWithPreload.js- * @param {import('@apollo/react-hoc/lib/types').OperationOption & PreloadOperationOptions} options
+ * @param {import('react-apollo').OperationOption & PreloadOperationOptions} options
...
- /** @type {import('@apollo/client').ApolloClient | null} */
+ /** @type {import('apollo-client').ApolloClient | null} */
...src/web/core/shop/ShopContext.js- * @property {import('@apollo/react-hoc').DataValue<{ shop: Shop, loading: boolean, error: import('apollo-client').ApolloError }, {}>} data
+ * @property {import('react-apollo').DataValue<{ shop: Shop, loading: boolean, error: import('apollo-client').ApolloError }, {}>} datasrc/web/theme/modules/SmartForms/Field/Email/useEmailServerValidation.js-import { useApolloClient } from "@apollo/react-hooks";
+import { useApolloClient } from "react-apollo";src/web/theme/modules/SmartForms/Field/PhoneNumber/usePhoneNumberValidation.js-import { useLazyQuery } from "@apollo/react-hooks";
+import { useLazyQuery } from "react-apollo";src/web/theme/modules/SmartForms/Field/helpers/useLazyQueryAlwaysTriggeredOnComplete.js-import { useLazyQuery } from "@apollo/react-hooks";
+import { useLazyQuery } from "react-apollo";
+
+/**
+ * @typedef {typeof useLazyQuery} UseLazyQuery
+ * @typedef {Parameters<UseLazyQuery>} UseLazyQueryParams
+ * @typedef {ReturnType<UseLazyQuery>} UseLazyQueryReturn
+ */
/**
* @callback OnCompletedCallback
* @param {any} data
*/
/**
* @typedef {Object} QueryResultsRef
* @property {OnCompletedCallback} onCompleted
* @property {boolean} loading
* @property {import('apollo-client/errors/ApolloError').ApolloError} error
* @property {any} data
- * @property {import('@apollo/react-common').OperationVariables} variables
+ * @property {UseLazyQueryReturn[1]["variables"]} variables
*/
/**
- * @param {import('graphql').DocumentNode} Query
- * @param {import('@apollo/react-hooks/lib/types').LazyQueryHookOptions} options
- * @returns {import('@apollo/react-hooks/lib/types').QueryTuple<any,import('@apollo/react-common').OperationVariables>}
+ * @param {UseLazyQueryParams[0]} Query
+ * @param {UseLazyQueryParams[1]} options
+ * @returns {UseLazyQueryReturn}
*/src/web/theme/modules/Wishlist/AddAllWishlistToCartModal/useAddAllWishlistToCartModalInternal.js-import { useMutation } from "@apollo/react-hooks";
+import { useMutation } from "react-apollo";src/web/theme/modules/Wishlist/WishlistProvider/WishlistProvider.js-import { useLazyQuery, useQuery } from "@apollo/react-hooks";
+import { useLazyQuery, useQuery } from "react-apollo";src/web/theme/pages/Account/DownloadableProduct/EnhanceDownloadableProduct.js- * @param {import('@apollo/react-hoc/lib/types').OptionProps<any, GraphQLData, any>} param0
+ * @param {import('react-apollo').OptionProps<any, GraphQLData, any>} param0src/web/theme/pages/Orders/Orders.js-import { useLazyQuery } from "@apollo/react-hooks";
+import { useLazyQuery } from "react-apollo";src/web/theme/pages/Product/useProductBySkuLoader.js-import { useQuery } from "@apollo/react-hooks";
+import { useQuery } from "react-apollo"; -
If after the above fixes there is still
@apollo/*
dependencies and you are not sure how to resolve please contact us for support. You can also check here and here for the changes we did to our codebase. -
Resolvers for fields that are not in the
schema
now throw errors. To avoid this remove all unneededfield
/Type
resolvers that do not have a representation in the GraphQLschema
. Check our cleaning commit regarding this issue. -
makeApolloClientStub
now expects resolvers as an argument instead of mocks. This is in tandem with thegraphql-tools
upgrade notes. Note that we provided an adapter that convertsmocks
toresolvers
so that old tests are not affected. However it is recommended to make the change. To disable the adapter's warning setFRONT_COMMERCE_WEB_PRINT_MAKEAPOLLOCLIENTSTUB_MOCKS_DEPRECATION_WARNING
environment variable to"false"
. -
The use of
SchemaVisitor
/SchemaDirectiveVisitor
to implement GraphQL directive is deprecated and it is replaced by the use of the new API. We implemented an adapter so that uses ofSchemaVisitor
/SchemaDirectiveVisitor
will not break, however it is recommended to make the change. Please note that the adapter only supports the use ofvisitFieldDefinition
function of theSchemaVisitor
/SchemaDirectiveVisitor
class. If you have use for other functions and cannot make the change to the new API please contact us for help. -
When using Node 17 you need to prefix your npm commands by
NODE_OPTIONS=--openssl-legacy-provider
e.g.NODE_OPTIONS=--openssl-legacy-provider npm start
,NODE_OPTIONS=--openssl-legacy-provider npm run build
. -
When using npm >= 7 you need to add
--legacy-peer-deps
to npm install commands. e.g.npm install --legacy-peer-deps
,npm i some_dependency --legacy-peer-deps
. -
Reinstall your dependencies after the update:
- For npm >= 7
- For npm < 7
rm -rf ./node_modules/
npm install --legacy-peer-deps
rm -rf ./node_modules/
npm install
New features in 2.15.0
β
- In-Stock Alerts
- Prismic: embed fields
- Magento2: use the native search capabilities of Magento for PLP
- npm 7 / NodeJS 16 / NodeJS 17 compatibility
- Integrate Paypal w. Adyen for a seamless checkout experience
2.13.0
-> 2.14.0
β
New style sheet for B2Bβ
In this release we updated the RequisitionList configurable options modal. In
case you are using the B2B module and have overridden
modules/front-commerce-b2b/web/theme/modules/RequisitionList/_RequisitionList.scss
please add the following line to it:
@import "~theme/modules/RequisitionList/ProductConfigurationModal/ProductConfigurationModal";
withFlashMessages
now exports hooksβ
The logic of withFlashMessages
is now also exported as a hook
useFlashMessages
. If you have overridden withFlashMessages
please apply the
changes in
this diff
to it.
Added downloadable products support for Magento2β
Minimum required magento 2 module version 2.6.1
Support for shareable downloadable products was added. There is now a new page
under the user account /user/downloadable-products
that lists all the
downloadable products of the current user.
P.S. The withFlashMessage update is required for the downloadable product page.
To add a link to the downloadable products in the account navigation please apply the following diffs to your project:
If you are using the base theme:
If you are using theme chocolatine:
PaymentMethodLabel relocatedβ
The <PaymentMethodLabel>
component was moved from
theme/modules/User/Order/OrderMethod/PaymentMethodLabel.js
to
theme/modules/Checkout/Payment/PaymentMethodLabel.js
the old location will
still work but will output deprecation messages when used. If you have
overridden <PaymentMethodLabel>
you should also relocate your override to the
same path and update all references to point to it.
As a consequence of relocating <PaymentMethodLabel>
we had to rename all the
translation keys it uses. As such the following translation keys have been
updated
Old Key | New Key |
---|---|
modules.User.Order.OrderMethod.PaymentMethod.checkmo | modules.Checkout.Payment.PaymentMethodLabel.checkmo |
modules.User.Order.OrderMethod.PaymentMethod.ogoneFlexcheckout | modules.Checkout.Payment.PaymentMethodLabel.ogoneFlexcheckout |
modules.User.Order.OrderMethod.PaymentMethod.paymentOnAccount | modules.Checkout.Payment.PaymentMethodLabel.paymentOnAccount |
modules.User.Order.OrderMethod.PaymentMethod.paypalButton | modules.Checkout.Payment.PaymentMethodLabel.paypalButton |
modules.User.Order.OrderMethod.PaymentMethod.paypalExpress | modules.Checkout.Payment.PaymentMethodLabel.paypalExpress |
modules.User.Order.OrderMethod.PaymentMethod.paypalStandard | modules.Checkout.Payment.PaymentMethodLabel.paypalStandard |
modules.User.Order.OrderMethod.PaymentMethod.payzenEmbedded | modules.Checkout.Payment.PaymentMethodLabel.payzenEmbedded |
modules.User.Order.OrderMethod.PaymentMethod.stripe | modules.Checkout.Payment.PaymentMethodLabel.stripe |
modules.User.Order.OrderMethod.PaymentMethod.hipay | modules.Checkout.Payment.PaymentMethodLabel.hipay |
All translation keys that start with
modules.User.Order.OrderMethod.PaymentMethod
now starts with
modules.Checkout.Payment.PaymentMethodLabel
. You need to update any use of the
old keys (if any) in your project to the respective new key.
Update your CSPsβ
In this release, we have removed most of the module-related CSPs from
Front-Commerce default configuration file. If you are using one or more of the
following modules, please do update your CSPs accordingly in your
config/website.js
configuration:
Google Analytics
orGoogle Tag Manager
(see analytics configuration)Paypal
(see Paypal configuration)Payzen
(see Payzen configuration)
Removed deprecations in Button
componentβ
The properties that were tagged as deprecated in
theme/components/atoms/Button/Button.js
before version 2.0 have been removed
in this release:
appearance
should now be used instead ofprimary
,icon
,link
andwarning
.state
should now be used instead ofdisabled
andpending
.
Please update your code to fit the new behavior.
Code clean upβ
In this release, we have removed some dead and unused code (see corresponding MR):
src/theme/pages/Account/Account.js
that despites its name is not used at all and very unlikely to be used by any project- some loadable routes from
src/web/LoadableRoutes.js
there were useless since the addition of file based routing in2.0.0-rc.0
.
If you have trouble about those removals while upgrading, please contact us.
Fixed the Front-Commerce B2B module's company credit displayβ
In the account menu we displayed the company credit menu even for companies not allowed to pay on account.
If you overrode FirstnameQuery.gql
add the following code
query Firstname {
me {
...
company {
name
+ credit {
+ availableCredit {
+ amount
+ }
+ }
}
}
}
If you overrode AccountNavigation.js
perform the following changes
...
const isCompanyUser = (user) => {
return Boolean(user?.company);
};
+const isCompanyCreditsAllowed = (user) => {
+ return Boolean(user?.company?.credit);
+};
...
- isCompanyUser(user) && {
+ isCompanyCreditsAllowed(user) && {
value: "/user/company/credit",
label: intl.formatMessage(messages.companyCredit),
},
...
- {isCompanyUser(user) && (
+ {isCompanyCreditsAllowed(user) && (
<Route
exact
path={`${basePath}/company/credit`}
children={({ match }) => (
<Link to="/user/company/credit" className={makeClassName(match)}>
{intl.formatMessage(messages.companyCredit)}
<Icon icon="cash" title="" />
</Link>
)}
/>
...
New features in 2.14.0
β
- Custom routable pages now supports dynamic GraphQL variables from URL
- New
FRONT_COMMERCE_GRAPHQL_PERSISTED_QUERIES_DISABLE
environment variable for temporarily deactivating the GraphQL Persisted Queries feature - New Prismic module features:
- Support for trailing slashes
- Support for path rewrites
- Exposed the
url
to the Content type
When a Prismic document has been registered using the
registerRoutableType
method or the
registerPrismicRoute
method, A url
property is exposed in the
Content type object.
This property contains the resolved url of the document.
2.12.0
-> 2.13.0
β
Upgrade the Magento2 moduleβ
If you are using Magento2, version 2.6.0 of front-commerce/magento2-module
is
now the minimum required version. To update it to the latest version, from
Magento2 root, you can run:
composer update front-commerce/magento2-module
You can refer to the Magento2
module
changelog
for the full details.
Upgrade the Prismic moduleβ
The front-commerce-prismic
module is now using the latest version of prismic.
npm install git+ssh://git@gitlab.blackswift.cloud/front-commerce/front-commerce-prismic.git#1.0.0
The most notable breaking changes is the removal of the
FRONT_COMMERCE_PRISMIC_URL
and the inclusion of the path
option for the
registerRoutableType
method.
You can refer to the front-commerce-prismic
module
changelog
for the full details.
FRONT_COMMERCE_PRISMIC_URL
has been removedβ
The environment variable FRONT_COMMERCE_PRISMIC_URL
has been removed. Please
use FRONT_COMMERCE_PRISMIC_REPOSITORY_NAME
instead.
- FRONT_COMMERCE_PRISMIC_URL=https://my-repo.prismic.io
+ FRONT_COMMERCE_PRISMIC_REPOSITORY_NAME=my-repo
Improved the registerRoutableType
methodβ
-
A new required property has been added for dynamic routes:
path
Examples:/:uid
,/:lang/:uid
,/:category*/:uid
,/:section/:category?/:uid
.ProTipβ’You can use the online express-route-tester@2.0.0 to test your paths.
-
A new
resolvers
property to allow the nested routes content relationship resolution.PrismicLoader.registerRoutableType({
typeIdentifier: "album", // document type "album" will resolve to path `/albums/:uid`
- path: "/album/:uid", // "/album/queen"
+ path: "/:category/:uid", // "/rock-and-roll/queen"
+ resolvers: {
+ category: "category" // identifier of the Content Relationship in the album Custom Type
+ },
...
})
The Route Resolver is limited to retrieving data from 2 levels deep, please see the Route Resolver example for more information.
@prismicio/client
has been updated to v6β
See https://prismic.io/docs/technologies/prismic-client-v6-migration-guide for the complete migration guide
The new predicate object contains the same predicate functions as Predicates with new names to better match the API's predicate names.
- import { Predicates } from "@prismicio/client";
+ import * as prismic from "@prismicio/client";
const query = new ListQuery(10)
- query.addPredicate(prismic.Predicates.gt('my.movie.rating', 3))
+ query.addPredicate(prismic.predicate.numberGreaterThan('my.movie.rating', 3))
The following predicates
have been renamed:
dayOfMonth
βdateDayOfMonth
dayOfMonthAfter
βdateDayOfMonthAfter
dayOfMonthBefore
βdateDayOfMonthBefore
dayOfWeek
βdateDayOfWeek
dayOfWeekAfter
βdateDayOfWeekAfter
dayOfWeekBefore
βdateDayOfWeekBefore
month
βdateMonth
monthBefore
βdateMonthBefore
monthAfter
βdateMonthAfter
year
βdateYear
hour
βdateHour
hourBefore
βdateHourBefore
hourAfter
βdateHourAfter
gt
βnumberGreaterThan
lt
βnumberLessThan
inRange
βnumberInRange
near
βgeopointNear
prismic-dom
replaced with @prismicio/helpers
β
See https://prismic.io/docs/technologies/prismic-helpers-v2-migration-guide for the complete migration guide
Added FlashMessages to the Order Detailsβ
For the HiPay payment method, FlashMessages may be shown at the order detail level for errors.
If you overrode <OrderDetailsLayout>
add the following lines to it
+ import FlashMessages from "theme/modules/FlashMessages";
...
return (
<div
className={classNames("order-details-layout", {
"account-orders-details--no-actions": !showOrderActions,
})}
>
+ <FlashMessages />
...
Login Form Updateβ
For the external logins feature <AdditionalLoginFormActions>
and
<FlashMessages>
have been added to the <LoginForm>
.
If you overrode <LoginForm>
please add the following lines to it
...
+import AdditionalLoginFormActions from "theme/modules/User/LoginForm/AdditionalLoginFormActions";
+import FlashMessages from "theme/modules/FlashMessages";
...
{props.errorMessage && <ErrorAlert>{props.errorMessage}</ErrorAlert>}
+ <FlashMessages />
...
</SubmitButton>
+ <AdditionalLoginFormActions />
</FormActions>
...
New icons requiredβ
In this release, these new icons were added google
, facebook
to the <Icon>
component theme/components/atoms/Icon/Icon.js
.
If you have overridden the <Icon>
component, you need to add the icons as
follows to the list of icons to avoid any error messages at page loading:
-import { FaUserCircle } from "react-icons/fa";
+import { FaUserCircle, FaFacebook, FaGoogle } from "react-icons/fa";
const keyToComponent = {
...
organigram: GiOrganigram,
gripper: VscGripper,
+ facebook: FaFacebook,
+ google: FaGoogle,
};
New features in 2.13.0
β
These new features may be relevant for your existing application:
- Search for products, categories and pages with Algolia in Magento2 based project
- Search for categories and pages with Algolia in Magento1 based project
- Prismic Preview
- HiPay payment method
- Facebook and Google external logins
2.11.0
-> 2.12.0
β
Upgrade the Magento2 moduleβ
If you are using Magento2, version 2.5.0 of front-commerce/magento2-module
is
now the minimum required version. To update it to the last version, from
Magento2 root, you can run:
composer update front-commerce/magento2-module
Homogenize the Map
componentsβ
To ensure a more consistent usage we have homogenize the props of the map components and we added a few fixes.
- The
LocationInternalShape
has been deprecated in favor ofLocationInputShape
. - The
CoordinatesShape
now accepts either longitude or lng. - Included the
onBoundsChanged
prop in theMap
components
For a list of available props for the map and marker components see: Display a map
carousel
image formatβ
To support
the Slider and Slider Magento2 page builder content types,
we have moved the <Carousel />
component from theme chocolatine to the default
theme. If you plan to use this component directly or through the page builder
Slider, you must add a carousel
image format to your src/config/images.js
:
@@ -6,6 +6,7 @@ module.exports = {
large: { width: 1100, height: 1100, bgColors: [] },
+ carousel: { width: 1280, height: 600, bgColors: [] },
zoomable: { width: 1100, height: 1100, bgColors: [], sizes: [2] },
},
};
swatch
image format in base themeβ
We backported the swatch
image format from theme chocolatine to base theme.
This image format is used to display product images of a requisition list. If
you are using the base theme and want to use the requisition list feature of the
B2B module you have to add the swatch image format to your
src/config/images.js
as follows:
module.exports = {
defaultBgColor: "FFFFFF",
presets: {
...
+ swatch: { width: 26, height: 26, bgColors: [] },
...
},
};
Smarter image resizing mechanismβ
In this release, we have improved the image resizing mechanism to be bit
smarter. Before this release, a check on the requested file extension was done
before trying to resize an image. As of this release, this check has been
removed and it's now up to the underlying image processing library to check if
this file is a image or not. As a result, out of the box, more image file
formats can be processed without any configuration. The extensions
setting
from config/images.js
becomes useless and is now deprecated. You should remove
it from your application:
large: { width: 1100, height: 1100, bgColors: [] }
},
- extensions: [".jpg", ".jpeg", ".png"]
};
Added requisition list features to B2B module (only theme chocolatine suported)β
If you are using base theme and wish to use the B2B module you have to override
theme/modules/ProductView/Synthesis/AddProductToCart.js
from the base theme
and provide a way to add to requisition list from the product page (see
AddProductToRequisitionList
and
B2B's AddProductToCart
for inspiration). You also need to override
theme/modules/AddToCart/_AddToCart.scss
if you have not already and just copy
the styles from the base theme to it
(src/web/theme/modules/AddToCart/_AddToCart.scss
).
If you are using theme chocolatine and have overridden
theme/modules/ProductView/Synthesis/AddProductToCart.js
and want to use the
B2B module you need to apply the following change to it:
...
+import AddProductToRequisitionList from "theme/modules/RequisitionList/AddProductToRequisitionList";
...
<AddToCart
appearance={appearance}
selectedOptions={selectedOptions}
selectedCustomOptions={selectedCustomOptions}
selectedBundleOptions={selectedBundleOptions}
onProductAdded={onProductAdded}
product={withComputedPrice(product)}
label={intl.formatMessage(messages.addToCartLabel)}
unavailableLabel={intl.formatMessage(messages.unavailableLabel)}
actions={
- withWishlist !== false && (
+ <>
+ {withWishlist !== false && (
<AddProductToWishlist
sku={product.sku}
selectedOptions={selectedOptions}
selectedCustomOptions={selectedCustomOptions}
selectedBundleOptions={selectedBundleOptions}
size="big"
/>
- )
+ )}
+ <AddProductToRequisitionList
+ product={product}
+ selectedConfigurableOptions={selectedOptions}
+ size="big"
+ />
+ </>
}
/>
...
If you overrode theme/modules/Cart/CartTitle/CartTitle.js
you need to apply
the following diff to it:
...
+import AddCartToRequisitionList from "../../RequisitionList/AddCartToRequisitionList";
...
<FormActions appearance="center">
+ <AddCartToRequisitionList cart={props.cart} size="big" />
{hasCartError ? (
<Button onDisableClick={() => {}} state="disabled">
<ProceedToCheckout />
</Button>
) : (
<Link to="/checkout" buttonAppearance="primary">
<ProceedToCheckout />
</Link>
)}
</FormActions>
...
Cookies max age configurationβ
The cookieMaxAgeInMonths
configuration in src/config/website.js
represents
the consent cookie's maxage in months. It now has a default value of 12
months. Previously if left unconfigured the cookie banner will appear to users
every time they visit the site.
New links added to <AccountNavigation>
β
The company structure and requisition list links are added to the
<AccountNavigation>
component. Those links are part of the B2B features so if
you need them and overrode the <AccountNavigation>
component you need to apply
the below diff to your overridden <AccountNavigation>
:
"AccountNavigation" diff (click to expand diff)
import React from "react";
...
const messages = defineMessages({
...
+ companyStructureLink: {
+ id: "pages.Account.Navigation.companyStructure",
+ defaultMessage: "Company structure",
+ },
...
+ requisitionListsLink: {
+ id: "pages.Account.Navigation.requisitionLists",
+ defaultMessage: "Your requisition lists",
+ },
...
});
...
export const MobileSelector = injectIntl(
({
intl,
location,
ordersCount,
storeCredit,
wishlist,
+ requisitionList,
user,
returnMerchandiseAuthorization,
}) => {
const companyRoutes = isCompanyUser(user)
? [
...
+ {
+ value: "/user/company/structure",
+ label: intl.formatMessage(messages.companyStructureLink),
+ },
]
: [];
const routes = [
...
+ requisitionList?.isFeatureActive && {
+ value: "/user/requisition-lists",
+ label: intl.formatMessage(messages.requisitionListsLink),
+ },
...
].filter(Boolean);
...
}
);
...
export const DesktopLeftMenu = injectIntl(
({
intl,
basePath,
ordersCount,
storeCredit,
wishlist,
user,
+ requisitionList,
returnMerchandiseAuthorization,
}) => {
return (
<nav className="account-navigation">
...
{isCompanyUser(user) ? (
<>
...
+ <Route
+ exact
+ path={`${basePath}/company/structure`}
+ children={({ match }) => (
+ <Link
+ to="/user/company/structure"
+ className={makeClassName(match)}
+ >
+ {intl.formatMessage(messages.companyStructureLink)}
+ <Icon icon="organigram" title="" />
+ </Link>
+ )}
+ />
</>
) : null}
...
+ {requisitionList?.isFeatureActive && (
+ <Route
+ path={`${basePath}/requisition-lists`}
+ children={({ match }) => (
+ <Link
+ to="/user/requisition-lists"
+ className={makeClassName(match, ordersCount === 0)}
+ >
+ {intl.formatMessage(messages.requisitionListsLink)}
+ <Icon icon="list" title="" />
+ </Link>
+ )}
+ />
+ )}
...
</nav>
);
}
);
New style sheetsβ
If you overrode theme/components/_components.scss
you need to add the
following line to it
@import "~theme/components/molecules/LoadingOverlay/LoadingOverlay";
@import "~theme/components/molecules/SelectMenu/SelectMenu";
If you overrode theme/components/_modules.scss
you need to add the following
line to it to use the <ProductPicker>
component (used by
the QuickOrder feature)
@import "~theme/modules/ProductPicker/ProductPicker";
If you are using the B2B module and overrode theme/_b2b.scss
you need to add
the following lines to it
@import "~theme/components/organisms/Tree/Tree";
@import "~theme/modules/Company/CompanyStructure/CompanyStructure";
@import "~theme/modules/RequisitionList/RequisitionList";
@import "~theme/modules/RequisitionList/RequisitionListTable/RequisitionListTable";
If you overrode src/web/theme/components/atoms/Button/_Button.scss
apply the
following diff to it:
- Base theme diff
- Theme chocolatine diff
...
+.button--disabled {
+ &:hover,
+ &:focus {
+ background: $white;
+ }
+}
...
.button--disabled {
+ &,
+ &:hover,
+ &:focus,
+ &:active {
+ background: $white;
+ text-decoration: none;
cursor: not-allowed;
border-color: $shade04;
background: $white;
color: $shade04;
&.button--primary {
border-color: $shade04;
background: $shade04;
color: $white;
}
&.button--icon {
background: transparent;
color: $shade04;
}
+ }
}
...
.button--disabled {
border-color: $shade03;
&:hover,
- &:focus {
+ &:focus,
+ &:active {
background: $white;
}
}
...
.button--disabled {
- cursor: not-allowed;
-
- &,
- &:hover {
+ &,
+ &:hover,
+ &:focus,
+ &:active {
+ text-decoration: none;
+ cursor: not-allowed;
border-color: $shade03;
background: $white;
color: $shade03;
&.button--primary {
border-color: $shade03;
background: $shade03;
color: $fontColor;
}
}
}
if you overrode theme/modules/AddToCart/_AddToCart.scss
and are using theme
chocolatine apply the following diff to it:
...
&__actions {
display: none;
padding: math.div($boxSizeMargin, 2);
@media screen and (min-width: $menuBreakpoint) {
display: block;
}
}
&__actions {
- display: none;
+ display: flex;
padding: math.div($boxSizeMargin, 2);
- @media screen and (min-width: $menuBreakpoint) {
- display: block;
- }
+ > * {
+ margin-left: math.div($boxSizeMargin, 2);
+ }
+ :first-child {
+ margin-left: 0;
+ }
}...