v21.This release contains breaking changes.
This version marks the release of new Custom Application features.
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
v12 has been dropped. Recommended versions are v14 or v16.Upgrading ESLint to v8
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/reactversion12.xand@testing-library/react-hooksversion7.x.@commercetools-frontend/cypress: requirescypressversion8.x || 9.x.@commercetools-frontend/jest-stylelint-runner: requiresstylelintversion14.x.
Changes to Custom Application config
The Custom Application config file has some new required fields.
env.developmentoAuthScopes*.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": []
}
]
}
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.Referencing constants
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 = 'channels';
export const PERMISSIONS = entryPointUriPathToPermissionKeys(entryPointUriPath);
PERMISSIONS variable contains a View and Manage properties, with the values being the computed values based on the entryPointUriPath..mjs file extension):import { entryPointUriPath, PERMISSIONS } from './src/constants';
const config = {
entryPointUriPath,
mainMenuLink: {
permissions: [PERMISSIONS.View],
},
// ...
};
export default config;
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.
ENABLE_OIDC_FOR_DEVELOPMENT=true, this is now the default behavior and you can remove the environment variable.Recommended setup for EntryPoint
<EntryPoint> component we recommend to render the application content as children of <ApplicationShell> instead of the render prop.<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
mc-scripts CLI has some breaking changes about the commands:- In
mc-scripts, thebuildcommand additionally compiles theindex.htmlby default.- Running the
compile-htmlcommand by default should not be necessary anymore. However, you can pass--build-onlyto thebuildcommand 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-htmlcommand by default does not print tostdoutthe JSON string with the security headers. You can opt into the old behavior by passing the--print-security-headersoption. - The
--inline-cspofcompile-htmlhas been dropped, as it's now the built-in behavior. - The
distfolder created by thebuildcommand has been removed. Instead, thebuildcommand writes the production bundles directly into thepublicfolder.
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.
--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.
Changes to Test Utils
@commercetools-frontend/application-shell/test-utils has the following breaking changes:-
The
disableApolloMocksoption 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 themocksproperty with a non-empty array. See Testing for more information. -
The
disableAutomaticEntryPointRoutesoption now defaults tofalse. This means that when rendering the<ApplicationShell>, you should not use therenderfunction but pass the application component usingchildren.const EntryPoint = () => ( <ApplicationShell environment={window.app} applicationMessages={loadMessages} > <AsyncApplicationRoutes /> </ApplicationShell> ); -
The application
Viewpermission is automatically applied to theprojectobject, based on theenvironment.entryPointUriPathvalue. You can always override the permission values by explicitly assigningproject.allAppliedPermissions. -
The deprecated
project.allAppliedMenuVisibilitiesoption has been removed. -
The deprecated
permissionsoption has been removed. Useproject.allAppliedPermissionsinstead.// Before { permissions: { canManageProducts: true; } } // After { project: { allAppliedPermissions: [{ name: 'canManageProducts', value: true }]; } }You can also use the helper functionmapResourceAccessToAppliedPermissions(recommended)import { mapResourceAccessToAppliedPermissions } from '@commercetools-frontend/application-shell/test-utils'; { project: { allAppliedPermissions: mapResourceAccessToAppliedPermissions([ PERMISSIONS.View ]) }, }or thedenormalizePermissionsfunction.import { denormalizePermissions } from '@commercetools-frontend/application-shell/test-utils'; { project: { allAppliedPermissions: denormalizePermissions({ canManageProducts: true, }); } }
mapResourceAccessToAppliedPermissions or denormalizePermissions.@commercetools-frontend/cypress package to be able to use the cy.loginByOidc command. See End-to-End tests for more information.