Release Notes
Stay informed about important feature releases, announcements and more.
Introduced granular permissions for local development of Custom Applications
You can now have teams with limited permissions develop Custom Applications locally. Previously, the option of local development was only available to members belonging to the Administrators
team of an Organization.
For more information, see Granular permissions for local development within the Custom Applications documentation.
As always, if you have questions or feedback, open a GitHub discussion or issue.
Introduced the new main navigation menu for the Merchant Center
The new main navigation menu brings a fresh look and enhanced functionality to help you navigate your application effortlessly. It provides a smoother and intuitive user experience in the Merchant Center.
To use the new navigation menu, update the ui-kit
and app-kit
packages to the latest versions.
As always, if you have questions or feedback, open a GitHub discussion or issue.
Improved permission management for Custom Applications
You can now modify the permissions of your Custom Applications in both Draft and Ready states, a feature that was previously limited to the Draft state.
This enhancement allows you to make changes to permission, for example, adding new OAuth Scopes, managing permission groups, or removing unused scopes, all without uninstalling the application. With this update, all existing team permissions remain unaffected.
If you have questions or feedback, open a GitHub discussion or issue.
New UI style for the Merchant Center
You can now get your Custom Application to resemble the default applications in the redesigned Merchant Center. To achieve this, update the ui-kit
and app-kit
dependencies to the latest version. We don't expect you to do any extra work regarding the styles of your components in this regard.
The new Merchant Center design also brings new layout guidelines to display page content, and new UI components to implement the layouts. We recommend following these guidelines and using the layout components for your Custom Applications.
If you have questions or feedback, open a GitHub discussion or issue.
Custom Applications v22 and UI Kit v16
The Application Kit packages have been released with a new major version v22
, as well as the UI Kit packages with a major version v16
.
This release contains breaking changes.
This release contains some major dependency version updates. We don't expect any migration steps necessary aside some minor test adjustments (see migration steps below).
The following libraries have been updated to new major versions:
@commercetools-frontend/ui-kit
and all@commercetools-uikit/*
packages have been updated tov16
.react-intl
and@formatjs/cli
have been updated tov6
.jest
and@types/jest
have been updated tov29
.jsdom
has been updated tov21
.eslint-plugin-jest
has been updated tov27
.
Furthermore, we dropped support for Node.js v14
. Make sure you are using v16
or v18
at least.
Finally, we removed support for Google Analytics tracking. If you were using it via the trackingGtm
value, you would need to implement the setup on your own.
As always, if you have questions or feedback you can open a GitHub Discussion or a GitHub Issue.
Upgrading peer dependencies
Make sure to upgrade the following dependencies:
react-intl
and@formatjs/cli
tov6
jest
and@types/jest
tov29
jest-runner-eslint
tov2
jest-watch-typeahead
tov2
Migrating Jest
The package @commercetools-frontend/jest-preset-mc-app
contains most of the updates and migration changes.
We don't expect any specific migration effort besides updating all Jest dependencies to their latest version (including possible Jest plugins being used).
However, there are a couple of possible necessary updates to consider:
- Jest snapshots format changed a bit. You might need to update your snapshots by passing the option
-u
to the Jest command. - The ESLint plugin for Jest might yield some new errors due to its breaking changes. See changelog.
For more detailed information about upgrading Jest, please refer to the official guides:
Introducing consistent button sizes in the UI Kit
The size
prop on the UI Kit button components lets you set the size. However, the size
values across different button components were inconsistent. For example, the PrimaryButton
supported the small
and big
sizes while the SecondaryButton
only had the big
size.
Starting from UI Kit version 15.14.0
, the button components accept consistent values for the size
prop, as described below.
PrimaryButton
:
- Default size:
big
. - Available sizes:
medium
,big
. - Changes: Replaced the
small
size withmedium
for consistency. Thesmall
size will continue to work until the deprecation notice.
SecondaryButton
:
- Default size:
big
. - Available sizes:
medium
,big
. - Changes: Added the
medium
size.
PrimaryIconButton
:
- Default size:
big
. - Available sizes:
small
,medium
,big
. - Changes: No changes.
SecondaryIconButton
:
- Default size:
big
. - Available sizes:
small
,medium
, andbig
. - Changes: Added two new size options—
small
andmedium
.
As always, if you have questions or feedback, you can open a GitHub Discussion or a GitHub Issue.
Custom Applications deployment previews
Custom Applications now let you generate deployment previews, where you can test new features without affecting the production version of your application.
If you're using the legacy workaround of creating multiple Custom Applications with different entry points, we recommend migrating to deployment previews. They provide a better developer experience with less maintenance since you only need to configure one Custom Application.
As always, if you have questions or feedback, you can open a GitHub Discussion or a GitHub Issue.
Support logging in via Single Sign-On for local development
When developing a Custom Application locally, you are prompted to authorize your user via the login form. From now on, it is possible to log into the Merchant Center using Single Sign-On for local development as well.
As always, if you have questions or feedback, you can open a support ticket.
Custom Applications multiple permissions
The Application Kit packages have been released with a minor version v21.21.0
.
Custom Applications now allow defining more granular OAuth Scopes and user permissions to cover more specific business requirements. You can create multiple permission groups and assign different OAuth Scopes to them. These permission groups can then be assigned to teams in a more granular way.
As always, if you have questions or feedback, you can open a GitHub Discussion or a GitHub Issue.
Human-readable page titles
Custom Applications now use a more readable, customizable document title by default. You can read more about this feature in the Human-readable page title documentation.
As always, if you have questions or feedback, you can open a GitHub Discussion or a GitHub Issue.
Support for configuring custom HTTP clients
By default Custom Applications provide pre-configured HTTP clients for GraphQL and REST API requests.
However, you could use any other HTTP client of your choice, for example Fetch, Axios, Stale-While-Revalidate (SWR), etc.
The main problem with that is the fact that you need to configure these clients on your own, in particular regarding the HTTP headers that should be sent with every request.
To make it easier to configure your HTTP client with the necessary HTTP headers, we provide some dedicated utility functions, in particular the executeHttpClientRequest.
As always, if you have questions or feedback you can open a GitHub Discussion or a GitHub Issue.
Installing Custom Applications in multiple Organizations
With the release of Org-level Custom Applications, one of the long-term goals for this feature was to enable Custom Applications to be configured only once and installed everywhere needed.
Up until now, this functionality was limited to installing a Custom Application in the same Organization where it was configured. This limitation was mainly posed to reduce the scope of the initial release.
As of today, we are happy to announce that Custom Applications can be installed in other Organizations where the user has administration rights.
If you are managing multiple Organizations, you can configure a Custom Application in one of them and install it across the different Organizations where you are a member of the Administrators Team. For more information check out the revised documentation for Configuring and Managing Custom Applications.
As always, if you have questions or feedback you can open a GitHub Discussion or a GitHub Issue.
Migration deadline postponed for Org-level Custom Application
The migration deadline previously set to the end of July 2022 has been postponed to Friday, 16 September 2022.
This gives users a bit more time to finish the migration from Project-level Custom Applications.
As always, if you have questions or feedback you can open a GitHub Discussion or a GitHub Issue.
Custom Applications v21.8
The Application Kit packages have been released with a minor version v21.8
.
This release includes several new features that we would like to present:
- Official support for developing Custom Applications in TypeScript, including a new starter template. Read more about TypeScript in the Adding TypeScript page.
- New policy option for configuring the
audience
field when integrating your Custom Application with an external API. - Improved accessibility of different elements using ARIA attributes.
- Simpler and more readable list of time zone data, available from the
@commercetools-frontend/l10n
package. - New React hook
useProjectExtensionImageRegex
for accessing the project images configuration, available from the@commercetools-frontend/application-shell-connectors
package.
As always, if you have questions or feedback you can open a GitHub Discussion or a GitHub Issue.
Deprecations
The mc-scripts
CLI has deprecated some entry points.
Importing the function createPostcssConfig
from the main entry point @commercetools-frontend/mc-scripts
is now deprecated. Use the entry point @commercetools-frontend/mc-scripts/postcss
instead.
const {
createPostcssConfig,
-} = require('@commercetools-frontend/mc-scripts');
+} = require('@commercetools-frontend/mc-scripts/postcss');
Importing the functions createWebpackConfigForDevelopment
and createWebpackConfigForProduction
from the main entry point @commercetools-frontend/mc-scripts
is now deprecated. Use the entry point @commercetools-frontend/mc-scripts/webpack
instead.
const {
createWebpackConfigForDevelopment,
createWebpackConfigForProduction,
-} = require('@commercetools-frontend/mc-scripts');
+} = require('@commercetools-frontend/mc-scripts/webpack');
Custom Applications become generally available
We are happy to announce that Custom Applications is now generally available.
After collecting feedback during the beta phase, and with the recent milestone of migrating Custom Applications to Org-level, we now have a solid foundation on the functionalities and developer tooling for Custom Applications.
Custom Applications v21.6
The Application Kit packages have been released with a minor version v21.6
.
This release includes several new features that we would like to present:
- A new built-in Stacking Layer System to automatically and consistently calculate
z-index
values of stacked modal containers. - New layout UI components
<InfoDetailPage>
,<FormDetailPage>
and<CustomFormDetailPage>
. - The CLI commands
config:sync
now lists changes when updating an existing Custom Application configuration. - The Jest preset
@commercetools-backend/jest-preset-mc-app
contains more Intl polyfills.
As always, if you have questions or feedback you can open a GitHub Discussion or a GitHub Issue.
Introducing the Stacking Layer System.
Background
Components such as modal pages, dialogs, etc. are rendered using a "modal" container. These containers are then rendered within a special container called portals-container
.
Up until now, rendering these components required to define things like zIndex
or level
props, to imperatively determine how the component will be visible.
This was required as the modal containers are positioned absolute
and finding the correct z-index
value is important.
However, it's the responsibility of the developer to "pick" the correct values which is error prone. In fact, choosing a wrong z-index
results in the modal to not be visible and thus leading to UI bugs.
A better and more reliable approach would be for the Custom Application to automatically determine the correct z-index
values for every modal container rendered on the page.
Stacking Layer System
To solve this issue, a Custom Application now implements a Stacking Layer System to automatically determine and apply the correct z-index
values for every modal container.
Therefore, it is not necessary anymore to explicitly provide the zIndex
and level
props to the modal pages or dialog components. The following props have been deprecated: level
and baseZIndex
(modal pages).
To remove the deprecated props you can run the codemod remove-deprecated-modal-level-props
:
$ npx @commercetools-frontend/codemod remove-deprecated-modal-level-props 'src/**/*.js'
For backwards compatibility, the zIndex
prop is still supported and, if defined, it will overwrite the z-index
value using !important
. Therefore we recommend to only define it if absolutely necessary, otherwise it's safe to remove it.
Custom Applications v21.3
The Application Kit packages have been released with a minor version v21.3
.
This release includes several new features that we would like to present:
- New CLI commands
login
andconfig:sync
to help maintaining Custom Applications. - New layout UI components
<TabularMainPage>
and<TabularDetailPage>
. In addition to that, a new<TabHeader>
component is exported from the@commercetools-frontend/application-components
package to be used in the tabular UI components<TabularModalPage>
,<TabularMainPage>
and<TabularDetailPage>
. - New ESLint config
@commercetools-backend/eslint-config-node
for Node.js projects with built-in TypeScript support. - The notification components now support the aria role
alertdialog
and thearia-describedby
attributes. This helps in particular to write more specific and relevant selector in tests.
As always, if you have questions or feedback you can open a GitHub Discussion or a GitHub Issue.
Custom Applications v21
The Application Kit packages have been released with a new major version v21
.
This release contains breaking changes.
This version marks the release of new Custom Application features. See Migrating from Project-level Custom Applications for more information.
Furthermore, the Custom Application documentation has been restructured and updated to match the new status quo of Custom Applications. The Project-level legacy documentation remains available during the migration period in a separate location.
Follow the steps below to migrate your Application Kit packages to the new version.
New documentation
The Custom Applications documentation has been restructured and improved to provide a better developer experience. During the migration period the Project-level legacy documentation remains available for maintenance and reference purposes.
Supported Node.js versions
Support for Node.js v12
has been dropped. Recommended versions are v14
or v16
.
Upgrading ESLint to v8
ESLint has been upgraded to v8
as the minimal required version. Make sure to upgrade the eslint
package to v8
and any other ESLint-related package to their latest version.
The upgrade might include some rule changes and therefore some lint errors that need to be fixed.
Changes to peer dependencies
The following packages have updated their peer dependencies requirements:
@commercetools-frontend/application-shell
: requires@testing-library/react
version12.x
and@testing-library/react-hooks
version7.x
.@commercetools-frontend/cypress
: requirescypress
version8.x || 9.x
.@commercetools-frontend/jest-stylelint-runner
: requiresstylelint
version14.x
.
Changes to Custom Application config
The Custom Application config file has some new required fields.
env.development
oAuthScopes
*.defaultLabel
In addition to that, the menu link structure also changed a bit.
// Before
{
"menuLinks": {
"icon": "HeartIcon",
"defaultLabel": "Starter",
"labelAllLocales": [],
"permissions": [],
"submenuLinks": [
{
"uriPath": "channels",
"defaultLabel": "Channels",
"labelAllLocales": [],
"permissions": []
}
]
}
}
// After
{
"icon": "${path:@commercetools-frontend/assets/application-icons/rocket.svg}",
"mainMenuLink": {
"defaultLabel": "Starter",
"labelAllLocales": [],
"permissions": [],
},
"submenuLinks": [
{
"uriPath": "channels",
"defaultLabel": "Channels",
"labelAllLocales": [],
"permissions": []
}
]
}
Note that there is a new required field defaultLabel
, which is used in case there is no localized label for the user's locale. If you don't need localized labels, you can leave the labelAllLocales
field empty and only use the defaultLabel
.
See Custom Application config for more information.
Referencing constants
The Custom Application config has support for additional file extensions. This allows us to reference certain variables in our Custom Application config and in other places of the application.
For example, we can define the entryPointUriPath
and the user permissions in a constants.js
file. The user permissions can be computed using the entryPointUriPathToPermissionKeys
function, to avoid defining them manually.
import { entryPointUriPathToPermissionKeys } from '@commercetools-frontend/application-shell/ssr';
export const entryPointUriPath = 'avengers';
export const PERMISSIONS = entryPointUriPathToPermissionKeys(entryPointUriPath);
The PERMISSIONS
variable contains a View
and Manage
properties, with the values being the computed values based on the entryPointUriPath
.
You can now reference these variables in the application code, as well as in the Custom Application config (using the .mjs
file extension):
import { entryPointUriPath, PERMISSIONS } from './src/constants';
const config = {
entryPointUriPath,
mainMenuLink: {
permissions: [PERMISSIONS.View]
},
// ...
};
export default config;
Migrating from menu.json
Support for the deprecated menu.json
file has been removed. The menu links must be defined now in the Custom Application config file.
Furthermore the DEV_ONLY__loadNavbarMenuConfig
prop of the <ApplicationShell>
has been removed as well.
New login workflow
Starting the Custom Application locally now redirects you to the login page of the Merchant Center production environment (as defined in the Custom Application config). Upon successful login, you are redirected back to your local development server with a valid session.
If you were using the opt-in feature ENABLE_OIDC_FOR_DEVELOPMENT=true
, this is now the default behavior and you can remove the environment variable.
See Development login via OpenID Connect for more information.
Recommended setup for EntryPoint
In the Custom Application <EntryPoint>
component we recommend to render the application content as children
of <ApplicationShell>
instead of the render
prop.
This allows the <ApplicationShell>
to pre-configure the application entry point routes. In addition to that, the entry point route is protected by the basic View
permission check. This means that a user without permissions of your Custom Application won't be able to access the Custom Application route.
import { ApplicationShell } from '@commercetools-frontend/application-shell';
const loadMessages = async (locale) => {
// ...
}
const AsyncApplicationRoutes = React.lazy(() => import('../../routes'));
const EntryPoint = () => (
<ApplicationShell
environment={window.app}
applicationMessages={loadMessages}
>
<AsyncApplicationRoutes />
</ApplicationShell>
);
export default EntryPoint;
Changes to the CLI
The mc-scripts
CLI has some breaking changes about the commands:
- In
mc-scripts
, thebuild
command additionally compiles theindex.html
by default.- Running the
compile-html
command by default should not be necessary anymore. However, you can pass--build-only
to thebuild
command to opt-out of the compilation step, in case you want to run it separately, for example to use the--transformer
.
- Running the
- Running the
compile-html
command by default does not print tostdout
the JSON string with the security headers. You can opt into the old behavior by passing the--print-security-headers
option. - The
--inline-csp
ofcompile-html
has been dropped, as it's now the built-in behavior. - The
dist
folder created by thebuild
command has been removed. Instead, thebuild
command writes the production bundles directly into thepublic
folder.
Better deployments support
With the new improvements in the developer tools, it's now even simpler to deploy a Custom Application to all the major hosting services. In fact, you can now take advantage of the GitHub integration with some of those hosting providers, without any extra effort around configuration.
Previously you would need to use the --transformer
option of the compile-html
command to configure the configuration file of the hosting provider.
Now most of the things are built-in and defined as defaults, removing the need to dynamically create a configuration file. As a result, configurations for the hosting provider can be defined statically, thus allowing to fully use the GitHub integration features.
Check out the deployment examples pages for more information.
Changes to Test Utils
The @commercetools-frontend/application-shell/test-utils
has the following breaking changes:
-
The
disableApolloMocks
option has been removed. By default, the Apollo mocks are deactivated. This is to encourage mocking via Mock Service Worker. To opt into the usage of Apollo mocks, you only need to pass themocks
property with a non-empty array. See Testing for more information. -
The
disableAutomaticEntryPointRoutes
option now defaults tofalse
. This means that when rendering the<ApplicationShell>
, you should not use therender
function but pass the application component usingchildren
.const EntryPoint = () => ( <ApplicationShell environment={window.app} applicationMessages={loadMessages} > <AsyncApplicationRoutes /> </ApplicationShell> )
-
The application
View
permission is automatically applied to theproject
object, based on theenvironment.entryPointUriPath
value. You can always override the permission values by explicitly assigningproject.allAppliedPermissions
. -
The deprecated
project.allAppliedMenuVisibilities
option has been removed. -
The deprecated
permissions
option has been removed. Useproject.allAppliedPermissions
instead.// Before { permissions: { canManageProducts: true; } } // After { project: { allAppliedPermissions: [{ name: 'canManageProducts', value: true }]; } }
You can also use the helper function
mapResourceAccessToAppliedPermissions
(recommended)import { mapResourceAccessToAppliedPermissions } from '@commercetools-frontend/application-shell/test-utils'; { project: { allAppliedPermissions: mapResourceAccessToAppliedPermissions([ PERMISSIONS.View ]) }, }
or the
denormalizePermissions
function.import { denormalizePermissions } from '@commercetools-frontend/application-shell/test-utils'; { project: { allAppliedPermissions: denormalizePermissions({ canManageProducts: true, }); } }
To help defining the list of applied permissions, you can use the helper function mapResourceAccessToAppliedPermissions
or denormalizePermissions
.
Note that if you were testing your Custom Application with Cypress, you need to use the @commercetools-frontend/cypress
package to be able to use the cy.loginByOidc
command. See End-to-End tests for more information.
Rewrite of Starter template
The Custom Application Starter template has been rewritten from scratch, to provide a better experience to new developers working on Custom Applications.
Below an overview of the most important changes:
- The template now has more built-in dev tools, like ESLint and Prettier.
- The template README has been cleaned up a bit.
- The template uses the new React JSX transform.
- The template uses the new menu links in application config.
- The template has a nicer landing/welcome page with useful links to get started.
- The template has a
channels
page, that fetches channels and renders them in a table. This is a good showcase of some of our best practices, for example to use hooks, to use GraphQL, to use notifications, to render data in a table (with pagination), etc. - The template has React-Testing-Library tests, including mocking GraphQL and using test data.
Furthermore, the @commercetools-frontend/create-mc-app
package now automatically derives the entryPointUriPath
from the folder name when installing the template. The value is then applied to the application config and other places in the source code.
Custom Applications v19
The Application Kit packages have been released with a new major version v19
.
This release contains breaking changes.
This version does not contain explicit changes in our packages but mainly updates to major versions of some of the depended upon libraries. For instance:
@commercetools-frontend/ui-kit
and all@commercetools-uikit/*
packages have been updated tov12
.react
andreact-dom
have been updated tov17
.graphql
has been updated tov15
.webpack
has been updated tov5
Furthermore, some peer dependencies have been updated to only require more recent versions. Please refer to each specific package's CHANGELOG.md
.
Migrating UI Kit packages
Constraints
For the <Constraints.Horizontal />
component, the deprecated constraint
prop has been removed. Now only the max
prop can be used instead.
- <Constraints.Horizontal constraint="m" />
+ <Constraints.Horizontal max={7} />
The equivalent mapping from constraint
to max
is as following:
| contraint
| max
|
| --- | --- |
| xs
(50px) | 1
(42px) |
| s
(132px) | 3
(142px) |
| m
(355px) | 7
(342px) |
| l
(496px) | 10
(484px) |
| xl
(768px) | 16
(784px) |
Text
{/* */}
For the <Text.Headline>
and <Text.Subheadline>
components, the deprecated elementType
prop has been removed. Now only the as
prop is used instead.
{/* */}
- <Text.Headline elementType="h2" intlMessage={message} />
+ <Text.Headline as="h2" intlMessage={message} />
{/* */}
For the <Text.Body>
and <Text.Detail>
components, the deprecated isInline
prop has been removed. Now only the as
prop can be used instead.
{/* */}
- <Text.Body isInline={true} intlMessage={message} />
+ <Text.Body as="span" intlMessage={message} />
Link
For the <Link>
component, the deprecated hasUnderline
prop has been removed. Links now always have an underline style applied.
When the prop isExternal
is used and the to
prop is not a string but a location object, an error is thrown.
Tag
For the <Tag>
component, the deprecated linkTo
prop has been removed. Now only the to
prop can be used instead.
SecondaryButton
For the <SecondaryButton>
component, the deprecated linkTo
prop has been removed. Now only the to
prop can be used instead.
GitHub Discussions available for application-kit and ui-kit repositories.
GitHub Discussions is finally generally available! 🎉
We have enabled it in a few selected open source repositories application-kit and ui-kit.
We strongly encourage and recommend to use that as a way of communicating with us (commercetools) and with the community. You can ask questions, share ideas, showcase your work, etc.
You can still use GitHub Issues in case you have to fill an bug report.
We are really excited about it and we hope you find it useful too.
Custom Applications v18
The Application Kit packages have been released as a new major version v18
.
This release contains breaking changes.
The changes relate to @commercetools-frontend/eslint-config-mc-app
package, where eslint
is now the only required peer dependency.
Additionally, the ESLint config uses the ESLint React App config as a base instead of Airbnb.
Most of the rules have stayed the same, however you may need to adjust or fix some depending on your usage.
In this release we also removed the long deprecated hostnames mc.commercetools.com
and mc.commercetools.co
from the default Content Security Policy configuration.
This is aligned with the long-running effort of moving the Merchant Center to use the new URLs.
If you still want to support your Custom Application to run on the legacy hostname for the remaining time being, you would need to explicitly add the legacy hostname(s) in the connect-src
config of the custom-application-config.json
.
Follow the steps below to migrate your ESLint config to the new version.
Migrating @commercetools-frontend/eslint-config-mc-app
Simply remove all ESLint related dependencies that where previously required as peer dependencies.
{
- "babel-eslint": "10.1.0",
"eslint": "7.18.0"
- "eslint-config-airbnb-base": "14.2.1",
- "eslint-config-prettier": "7.2.0",
- "eslint-plugin-babel": "5.3.1",
- "eslint-plugin-import": "2.22.1",
- "eslint-plugin-jest": "24.1.3",
- "eslint-plugin-jest-dom": "3.6.5",
- "eslint-plugin-jsx-a11y": "6.4.1",
- "eslint-plugin-prefer-object-spread": "1.2.1",
- "eslint-plugin-prettier": "3.3.1",
- "eslint-plugin-react": "7.22.0"
}
As a reminder, the ESLint config can be used as following:
module.exports = {
extends: ['@commercetools-frontend/eslint-config-mc-app'],
};
Custom Applications v17
The Application Kit packages have been released as a new major version v17
. One of the most important changes in this release is about migrating to the new Apollo Client v3
.
This release contains breaking changes.
Follow the steps below to migrate your Custom Application to the new versions.
Migrating to Apollo Client v3
Migrating to the new Apollo Client v3
requires some important migration steps.
Migrating Apollo imports
Apollo ships now with a single package @apollo/client
instead of multiple ones.
For Custom Applications this means that the peer dependencies apollo-client
and react-apollo
are now replaced with the new peer dependency of @apollo/client
.
This is all you need to do to migrate to the latest version of Apollo, including of course updating the Apollo imports.
About the new Apollo Cache
With Apollo v3
, the Apollo in-memory cache got some improvements as well, resulting in some breaking changes. Please make sure to read this document to understand the changes.
Depending on the GraphQL queries and mutations used by your Custom Application, it might be that the caching behavior of those queries needs to be adjusted. For example if objects do not have an id
field as identifier, or if Apollo cannot automatically merge two objects that have different fields shape, and so on.
If that is the case, you need to configure the Apollo cache according to your needs, as only you know what the best caching strategy for your Custom Application is.
To enable you to do so, the <ApplicationShell>
component now accepts an apolloClient
prop, that allows you to configure your own instance of the Apollo client with the custom cache configuration.
The @commercetools-frontend/application-shell
package exposes a createApolloClient
function that allows you to create a new Apollo client pre-configured with some important defaults (for example Apollo links, some basic cache policies, etc.).
import { createApolloClient, ApplicationShell } from '@commercetools-frontend/application-shell';
const apolloClient = createApolloClient({
cache: {
// Your custom configuration, according to the Apollo cache documentation.
// https://www.apollographql.com/docs/react/caching/cache-configuration/
},
});
const Application = () => {
return (
<ApplicationShell
apolloClient={apolloClient}
// ...other props
/>
);
};
Changes about Apollo query variables and context
Previously, to perform GraphQL requests to the Merchant Center API Gateway, you would need to specify request metadata options such as the GraphQL Target.
These values had to be specified in the query variables
object, which the built-in Merchant Center Apollo HTTP Link would parse and assign it to the request as HTTP headers. We call these options request context.
However, with a more stable support for the context
option in Apollo Client, we can pass the request metadata options to the context
object instead of the variables
object.
const { loading, data, error } = useQuery(MyQuery, {
- variables: {
+ context: {
target: GRAPHQL_TARGETS.COMMERCETOOLS_PLATFORM,
},
});
The request context options include:
target
projectKey
Passing the request metadata to the variables
object still works for backwards compatibility but it is recommended to use the context
object instead.
Enforcing a valid context object
The recommended and preferred way of passing request context is to use the context
object.
To improve the TypeScript support and auto-completion for the request context options, the @commercetools-frontend/application-shell
package now exports new React hooks. Note that autocompletion is possible, even if you are not using TypeScript.
useMcQuery
useMcLazyQuery
useMcMutation
These hooks are thin wrappers around the original Apollo hooks and have the same API, with a minor difference. Namely, the context
object is properly typed to conform with the Merchant Center request context instead of any
.
-import { useQuery } from '@apollo/client/react';
+import { useMcQuery } from '@commercetools-frontend/application-shell';
-const { loading, data, error } = useQuery(MyQuery, {
+const { loading, data, error } = useMcQuery(MyQuery, {
context: {
target: GRAPHQL_TARGETS.COMMERCETOOLS_PLATFORM,
},
});
Changes about the mc-scripts
CLI
Removing deprecated options from compile-html
Previously deprecated CLI options such as --env
, --csp
, --headers
, have been removed.
Additionally, the CLI flag --use-local-assets
has been removed as well. As such the default behavior of mc-scripts compile-html
changed to compile the assets locally.
When running the mc-scripts compile-html
command, the index.html
is compiled for production usage and it lives in the public
folder, together with the other static assets. This is all you need to deploy your application.
You can decide to deploy the Custom Application statically to one of the popular cloud providers, or serve the files on your own using a static server.
For example, to run locally the Custom Application using the production bundles:
NODE_ENV=production MC_APP_ENV=development dotenv -- \
mc-scripts compile-html \
--transformer @commercetools-frontend/mc-dev-authentication/transformer-local.js
mc-scripts serve
Removing the mc-http-server
package
The @commercetools-frontend/mc-http-server
package has been deprecated and will not receive any updates.
With the usage of the compile-html
command there is no need to have a pre-configured HTTP server anymore. If you are using this package, we recommend to use any other HTTP server package to serve your static files.
Remember that after building your production bundles you need to compile the Custom Application for production usage.
New command serve
We added a new command mc-scripts serve
that can be used to start your Custom Application locally in production
mode after it has been compiled.
The command starts an HTTP server to serve the static assets from the public
folder.
This command should only be used locally to test the Custom Application in production mode, as it contains the development routes for /login
and /logout
. Do not use this command to serve your Custom Application in production.
Before:
{
"start:prod:local": "NODE_ENV=production MC_APP_ENV=development dotenv -- mc-http-server --use-local-assets"
}
After:
{
"compile-html:local": "NODE_ENV=production MC_APP_ENV=development dotenv -- mc-scripts compile-html --transformer @commercetools-frontend/mc-dev-authentication/transformer-local.js",
"start:prod:local": "yarn compile-html:local && mc-scripts serve",
}
Removing the extract-intl
command
The mc-scripts extract-intl
command has been removed in favor of the official @formatjs/cli
package.
We recommend to update your script to extract Intl messages to use the formatjs extract
command.
Before:
{
"i18n:build": "mc-scripts extract-intl --output-path=$(pwd)/src/i18n/data 'src/**/!(*.spec).js' --build-translations"
}
After:
{
"extract-intl": "formatjs extract --format=$(pwd)/intl-formatter.js --out-file=$(pwd)/src/i18n/data/core.json 'src/**/!(*.spec).js'"
}
where the intl-formatter.js
should be defined as something like this, depending on your translation tool's needs:
// https://formatjs.io/docs/tooling/cli#extraction
exports.format = function format(extractedMessages) {
return (
Object.keys(extractedMessages)
// transform strings to lowercase to imitate phraseapp sorting
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
.reduce(
(allMessages, messageId) => ({
...allMessages,
// Return a simple key/value JSON object.
[messageId]: extractedMessages[messageId].defaultMessage,
}),
{}
)
);
};
Changes about the experimentalRenderAppWithRedux
from test utils
The experimental render method experimentalRenderAppWithRedux
from the test-utils
has been removed.
Instead, you should pass the disableApolloMocks
option to the renderApp
and renderAppWithRedux
methods. When this option is set to true
, the real ApolloProvider
is rendered instead of Apollo's MockProvider
.
This is useful if you want to mock requests at the network level, for example when using Mock Service Worker.
Additionally, you can also pass a custom apolloClient
instance together with the disableApolloMocks
option. This is only needed when your Custom Application uses a custom apolloClient
, for example for configuring the cache policies.
Removing the deprecated options from application-shell
The @commercetools-frontend/application-shell
package no longer exports the deprecated AsyncChunkLoader
and handleApolloErrors
.
Additionally, the deprecated prop trackingEventWhitelist
of the <ApplicationShell>
component has been removed as well.
Introducing a new and simpler application config
This release introduces the usage of a new configuration file format and marks the deprecation of the env.json
and headers.json
files.
The env.json
and headers.json
files will still keep working but they will be removed in the next major release.
The new configuration format aims to drastically simplify the configuration of a Custom Application. In addition, it also strives to make the configuration process less error prone. To achieve this, the new configuration file is backed by a JSON schema that is shipped together with the new package. The configuration file is then validated against the JSON schema.
Furthermore, the new configuration process tries to infer as much information as possible to reduce the amount of required fields.
Migrating to the new configuration file format
The new configuration file is a JSON file with one of the following names:
.custom-application-configrc
.custom-application-config.json
custom-application-config.json
The file is automatically loaded by the packages depending on it, so you don't need to explicitly specify it anywhere. This applies for instance to the mc-scripts
commands.
For example, given the following env.json
and headers.json
files:
{
"applicationName": "Avengers app",
"frontendHost": "localhost:3001",
"mcApiUrl": "https://mc-api.europe-west1.gcp.commercetools.com",
"location": "gcp-eu",
"env": "development",
"cdnUrl": "http://localhost:3001",
"servedByProxy": false
}
{
"csp": {
"script-src": [],
"connect-src": ["mc-api.europe-west1.gcp.commercetools.com"],
"style-src": []
}
}
and for production mode env.prod.json
and headers.prod.json
:
{
"applicationName": "Avengers app",
"frontendHost": "avengers.app",
"mcApiUrl": "https://mc-api.europe-west1.gcp.commercetools.com",
"location": "gcp-eu",
"env": "production",
"cdnUrl": "https://cdn.avengers.app",
"servedByProxy": true
}
{
"csp": {
"script-src": ["avengers.app", "cdn.avengers.app"],
"connect-src": [
"mc-api.europe-west1.gcp.commercetools.com",
"avengers.app",
"cdn.avengers.app"
],
"style-src": ["avengers.app", "cdn.avengers.app"]
}
}
To migrate them to the new format, add a custom-application-config.json
(or one of the other file names) with the following content:
{
"name": "Avengers app",
"entryPointUriPath": "avengers",
"cloudIdentifier": "gcp-eu",
"env": {
"production": {
"url": "https://avengers.app",
"cdnUrl": "https://cdn.avengers.app"
}
}
}
That's it! All other values are inferred from the config, like the Content-Security-Policy (CSP) headers, etc.
Additionally, note that the environment placeholder syntax ${env:VALUE}
continues to work.
Migrating mc-scripts
commands
The new configuration file is automatically loaded. Therefore, there is no need to explicitly pass the file path to the mc-scripts
commands in the package.json
{
"scripts": {
- "start:prod:local": "NODE_ENV=production dotenv -- mc-http-server --config=$(pwd)/env.json --headers=$(pwd)/headers.json --use-local-assets"
+ "start:prod:local": "NODE_ENV=production MC_APP_ENV=development dotenv -- mc-http-server --use-local-assets"
}
}
docker run \
-v $(pwd):/etc/app \
-p 8080:8080 \
- eu.gcr.io/ct-images/mc-http-server \
+ eu.gcr.io/ct-images/mc-http-server
- --config /etc/app/env.json \
- --headers /etc/app/headers.json
{
"scripts": {
- "compile-html": "mc-scripts compile-html --headers=$(pwd)/headers.prod.json --config=$(pwd)/env.prod.json --use-local-assets --transformer $(pwd)/transformer-vercel.js"
+ "compile-html": "mc-scripts compile-html --use-local-assets --transformer $(pwd)/transformer-vercel.js"
}
}
JSON Schema support for VSCode
In the VSCode settings (either user settings or workspace settings), reference the schema JSON as described below:
"json.schemas": [
{
"fileMatch": [
"/.custom-application-configrc",
"/.custom-application-config.json",
"/custom-application-config.json"
],
"url": "https://docs.commercetools.com/custom-applications/schema.json"
}
]
With that, the editor can offer autocompletion and validation of the JSON properties.
Migrate Custom Applications to the new host naming scheme
Recently we introduced a new host naming scheme for the commercetools APIs, including the Merchant Center, to increase region and cloud provider transparency.
While the previous hostnames such as *.sphere.io
(Google Cloud, Belgium), *.commercetools.com
(Google Cloud, Belgium), and *.commercetools.co
(Google Cloud, Iowa) continue to be operational, we strongly recommend to migrate to the new hostname structure.
~~In regards to Custom Applications, the runtime configuration needs to be updated to support both the new and the legacy hostnames to allow users to log in with the new Merchant Center hostname, and to be backwards compatible with the legacy hostnames.~~
If you are using the [new application config file][/development/application-config], you can ignore the migration steps as the hostnames are automatically configured.
Here are the steps to take.
1. Update dependencies
Make sure that the application kit dependencies are updated to at least version >= 16.2.1
, in particular the @commercetools-frontend/application-shell
package. This is important to ensure that certain functionalities related to the hostname migration are available.
To update all the application kit packages to a specific version, you can use the following script:
npx bulk-update-versions \
--match '^@commercetools-frontend/(?!ui-kit)(.*)' \
--force-latest
yarn install
The bulk-update-versions
script with the --force-latest
option bumps all packages matching the specified pattern to their latest
version.
If you are upgrading the application kit packages from older versions prior to v16
, follow the instructions in the changelogs.
2. Update the env.json
Change the mcApiUrl
in the env.json
to use the new hostname.
For example:
{
"applicationName": "merchant-center-application-template-starter",
"frontendHost": "localhost:3001",
"mcApiUrl": "https://mc-api.europe-west1.gcp.commercetools.com",
"location": "eu",
"env": "development",
"cdnUrl": "http://localhost:3001",
"servedByProxy": false
}
In production, the <ApplicationShell>
takes care of inferring the correct Merchant Center Gateway API hostname based on the Merchant Center hostname that the user is logged into.
This results in the Custom Application to work in both new and legacy hostnames, even though the mcApiUrl
is configured to a specific value.
This feature is available from version 16.2.1
onwards.
3. Update the headers.json
Update the Content Security Policy to allow both new and legacy hostnames.
For example:
{
"csp": {
"script-src": ["my-app.vercel.app"],
"connect-src": [
"my-app.vercel.app",
"mc-api.europe-west1.gcp.commercetools.com",
"mc-api.commercetools.com"
],
"style-src": ["my-app.vercel.app"]
}
}
4. Re-deploy the Custom Application
That's it. Re-deploy the Custom Application with the updated configuration. Users can now access the Custom Application using both new and legacy hostnames (for backwards compatibility).