All Release Notes

Custom Applications v21

2 February 2022
Announcement
DevelopmentGeneral

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 version 12.x and @testing-library/react-hooks version 7.x.
  • @commercetools-frontend/cypress: requires cypress version 8.x || 9.x.
  • @commercetools-frontend/jest-stylelint-runner: requires stylelint version 14.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.

constants.jsJavaScript
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):

custom-application-config.mjsJavaScript
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.

Changes to the CLI

The mc-scripts CLI has some breaking changes about the commands:

  • In mc-scripts, the build command additionally compiles the index.html by default.
    • Running the compile-html command by default should not be necessary anymore. However, you can pass --build-only to the build command to opt-out of the compilation step, in case you want to run it separately, for example to use the --transformer.
  • Running the compile-html command by default does not print to stdout the JSON string with the security headers. You can opt into the old behavior by passing the --print-security-headers option.
  • The --inline-csp of compile-html has been dropped, as it's now the built-in behavior.
  • The dist folder created by the build command has been removed. Instead, the build command writes the production bundles directly into the public 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 the mocks property with a non-empty array. See Testing for more information.

  • The disableAutomaticEntryPointRoutes option now defaults to false. This means that when rendering the <ApplicationShell>, you should not use the render function but pass the application component using children.

    entry-point.jsJavaScript
    const EntryPoint = () => (
    <ApplicationShell
    environment={window.app}
    applicationMessages={loadMessages}
    >
    <AsyncApplicationRoutes />
    </ApplicationShell>
    )
  • The application View permission is automatically applied to the project object, based on the environment.entryPointUriPath value. You can always override the permission values by explicitly assigning project.allAppliedPermissions.

  • The deprecated project.allAppliedMenuVisibilities option has been removed.

  • The deprecated permissions option has been removed. Use project.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.