commercetools Frontend SDK
The commercetools Frontend SDK is an event management tool that allows flexible and customizable frontend development. It also allows creating custom integrations that are backend-agnostic and backward-compatible. The commercetools Frontend SDK can be extended with additional SDKs and extensions that expose commercetools Frontend API integrations.
The current configuration of your commercetools Frontend project already implements the component library functionalities that the SDK simplifies, with the exception of event handling. Therefore, the SDK is helpful only if you need to build custom components that rely on extensions and integrations.
Install and set up the SDK
The SDK is released as an npm package. To install it in your commercetools Frontend project, follow these steps:
- Run
yarn add @commercetools/frontend-sdk
. - Run
yarn add @commercetools/frontend-domain-types
. - Set up the SDK and any additional extension packages in the same location, as shown in the example below.
The SDK and extensions must behave as singletons to prevent extensions from creating repeated events and multiple configuration calls.
It is recommended to use the latest version of all packages related to commercetools frontend SDK. The @commercetools/frontend-sdk
package will always be backward compatible, therefore having the latest version ensures you have all features and full compatibility with all your extensions.
Below is a template provided to use with the SDK and extensions to ensure singleton behaviour.
import { SDK } from '@commercetools/frontend-sdk';import {ComposableCommerce,ComposableCommerceEvents,} from '@commercetools/frontend-composable-commerce';// Add other extensions' custom events to the SDK's generic type here,// by extending ComposableCommerceEvents with their type using an intersection.// For example, <ComposableCommerceEvents & OtherEvents>.// You may also add your own custom events.class CommercetoolsSDK extends SDK<ComposableCommerceEvents> {composableCommerce!: ComposableCommerce;// Add your other extensions here.constructor() {super();this.composableCommerce = new ComposableCommerce(this);// Initialize your other extensions here.this.on('errorCaught', (event) => {// Handle any extension errors caught by the SDK globally.// For example, log error, fire notification, etc.console.log('SDK error: ', event.data);});// Set up any other custom global event handlers here.// Ensure types are created and added to the SDK generic type// if specific to your project.}}// Create a single instance of the SDK.const sdk = new CommercetoolsSDK();// Export only the instance to serve as a singleton throughout the project.export { sdk };
The previous example creates and exports an instance to ensure singleton behavior. However, the CommercetoolsSDK.ts
template file must be the single source of truth for anything related to the SDK and extensions. Therefore, it is recommended to store CommercetoolsSDK.ts
and index.ts
in a folder packages/<project>/frontend/sdk
for convention and ease of import.
import { sdk } from './CommercetoolsSDK';export { sdk };
Configure the SDK
Import and configure the SDK in an index location within your project, this needs to be called only once since the SDK is exported as a singleton. However, the SDK must be configured for both client-side and server-side rendering. The following example imports and configures the SDK in a Next.js project.
import { AppProps } from 'next/app';import { sdk } from '../sdk';sdk.configure({locale: 'de-DE',currency: 'EUR',endpoint: 'EXTENSION_RUNNER_HOSTNAME',});const Starter = ({ Component, pageProps }: AppProps) => {return <Component {...pageProps} />;};export default Starter;
For information on the extension runner hostname, see Main development concepts.
If needed, pass the useCurrencyInLocale
property to the configure
method. The default value is false
.
sdk.configure({locale: 'de-DE@EUR',currency: 'EUR',endpoint: 'EXTENSION_RUNNER_HOSTNAME',useCurrencyInLocale: true,});
You can import the configuration properties from the .env
file, a .config
file, or the getServerSideProps
call in Next.js for server-side rendering.
import { GetServerSideProps, Redirect } from 'next';import { mapSDKLanguage } from 'project.config';import { sdk } from '../sdk';type SlugProps = {...};export default function Slug({ data }: SlugProps) {...}export const getServerSideProps: GetServerSideProps | Redirect = async ({ params, locale, query, req, res }) => {sdk.configure({locale: mapSDKLanguage(locale),currency: 'EUR',endpoint: (process.env.NEXT_PUBLIC_FRONTASTIC_HOST ?? ”https://my.staging.server/frontastic”).split('/frontastic')[0],});...};
If the project uses only the SDK, no further configuration is required. If the project also uses extensions, you can call them from packages/<project>/frontend/sdk
.
The following example configures a Next.js project that uses the @commercetools/frontend-composable-commerce
extension. The getSettings
function is called on button click and applies the project settings. On component mount, the useEffect
React lifecycle hook adds an event handler to log the result of the fetch to the console. On component unmount, the event handler is cleaned up.
import { NextPage } from 'next';import React, { useEffect, useState } from 'react';import App from '../../components/App';import HorizontalSpacer from '../../components/horizontalSpacer';import { sdk } from '../../sdk';import Button from 'src/components/form/button';import { ProjectSettings } from '@commercetools/frontend-domain-types/ProjectSettings';const ExamplePage: NextPage = () => {const [projectSettings, setProjectSettings] = useState<ProjectSettings>();const [loading, setLoading] = useState(false);const projectSettingsReturnedEvent = (event: Event<'projectSettingsReturned',{settings: unknown;}>) => {// Access the commercetools Frontend project settings here.console.log('Event projectSettingsReturned fired: ', event.data.settings);};useEffect(() => {sdk.on('projectSettingsReturned', projectSettingsReturnedEvent);return () => {sdk.off('projectSettingsReturned', projectSettingsReturnedEvent);};}, []);const getSettings = async () => {setLoading(true);const response = await sdk.composableCommerce.project.getSettings();setLoading(false);if (!response.isError) {setProjectSettings(response.data);}};const style = { fontWeight: 'bold', textDecoration: 'underline' };return (<App><><h1>Example</h1><HorizontalSpacer /><Buttontext="TEST"onSubmit={projectSettings ? () => setProjectSettings(undefined) : getSettings}loading={loading}/><HorizontalSpacer />{projectSettings && (<><><h2 style={style}>NAME</h2><p>{projectSettings.name}</p></></>)}</></App>);};export default ExamplePage;