Learn about using various features of version 2 of the Frontend SDK.
Configure the SDK
configure method is defined on the base SDK main class in the @commercetools/frontend-sdk library and has several optional and required properties, the required properties will already be set up in your project using the defaultConfigure method in the CommercetoolsSDK.ts template file. The configure method supports the following options:-
locale- String - Required. The combination of the language and country code in ISO 639-1 and ISO 3166-1 format respectively. For example,en-DEoren_DE. In your code, you can access thelocalefrom thePageProps.params.locale(Next.js 12) or using theuseParams()hook (Next.js 13). -
currency- String - Required. The three-letter ISO 4217 Currency Code. For example,EUR. For more information, see supported currencies. -
endpoint- String - Required. The full URL of the API hub endpoint. -
extensionVersion- String - Required. The extension bundle version to connect to. -
useCurrencyInLocale- Boolean - Optional. Iftrue, the currency is required in thelocalein the formatLOCALE@CURRENCY. Defaults tofalse. Overrides thecurrencyoption. -
sessionLifetime- Number - Optional. This is the amount of time in milliseconds for which a user's session persists before needing to log in again. Overrides the default session lifetime of three months. -
customHeaderValue- String - Optional. This is the value sent as thecoFE-Custom-Configurationheader value with every request. You can override this value on a specific request by setting thecustomHeaderValueoption in the API methods. To access this value globally, call theSDK.customHeaderValue()function. -
cookieHandlingOverride- CookieManager - Optional. This option gives the user the ability to extend or override the default base SDK's CookieHandler.
The following code example shows how to extend the default cookie handling using thedefaultConfiguremethod in the SDK template file.import { sdk } from 'src/sdk'; import { CookieHandler, ServerOptions } from '@commercetools/frontend-sdk'; const cookieHandler = new CookieHandler(); sdk.configure({ ... cookieHandlingOverride: { setCookie: async (key: string, data: any, options?: ServerOptions) => { cookieHandler.setCookie(key, data, options); }, getCookie: async (key: string, options?: ServerOptions) => { return cookieHandler.getCookie(key, options); }, getCookies: async (options?: ServerOptions) => { return cookieHandler.getCookies(options); }, deleteCookie: async (key: string, options?: ServerOptions) => { return cookieHandler.deleteCookie(key, options); }, hasCookie: async (key: string, options?: ServerOptions) => { return cookieHandler.hasCookie(key, options); }, }, }); -
redactionHandlingOverride- RedactionManager and RedactionManagerConfig - Optional. This option lets the user override the default redaction behavior of the base SDK's events, such as redacting passwords from event properties and URL parameters.You can extend or override the default functionality by passing a class or object that implements the RedactionManager interface.
You can override the default redaction rules by passing a RedactionManagerConfig object.The following code example shows how to extend or override the default redaction handling methods using thedefaultConfiguremethod in the SDK template file.import { sdk } from 'src/sdk'; import { RedactionHandler, ServerOptions } from '@commercetools/frontend-sdk'; const redactionHandler = new RedactionHandler(); sdk.configure({ ... redactionHandlingOverride: { redact: async <T>(data: T) => { return redactionHandler.redact(data); }, redactUrl: async (url: string) => { return redactionHandler.redactUrl(data); } }, });The following code example shows how to override the default redaction handling configuration using thedefaultConfiguremethod in the SDK template file.import { sdk } from 'src/sdk'; import { RedactionManagerConfig, ServerOptions } from '@commercetools/frontend-sdk'; const customRedactConfig: RedactionManagerConfig = { paths: [{ value: "my.path.toRedact", caseSensitive: true }], properties: [], whitelistPaths: [{ "my.non_sensitive.password", caseSensitive: true }], includes: [{ value: "password" }, { value: "token" }], jsonRedactionText: "<CUSTOM_REDACT_TEXT>", urlRedactionText: "CUSTOM_URL_REDACT_TEXT", } sdk.configure({ ... redactionHandlingOverride: customRedactConfig, });
API methods
isError boolean property that you can use for narrowing. When isError is false, the response contains a data property with the return type from the API hub. When true, the response contains an error property that includes the error details. In both responses, the SDKResponse also contains tracing information for use in debugging and logging.callAction
callAction method lets you make requests to the action extensions. The method takes the expected return type as its generic argument that defines the type of data returned in the SDKResponse of a successful request. It also accepts the following options:-
actionName- String - Required. The name of the action extension to call. For example, useproduct/getProductto call the following extension:{ actions: { product: { getProduct: (...) => { ... } } } }. -
payload- AcceptedPayloadTypes - Optional. A payload object with key-value pairs to be serialized into the request body. -
query- AcceptedQueryTypes - Optional. An object of key-value pairs to be serialized into the request query parameters. -
parallel- Boolean - Optional. Defaults totrue. If set totrue, the action is executed asynchronously. If set tofalse, the action is added to a queue and executed in sequence. Setting to false is useful for actions that may cause race conditions. -
customHeaderValue- String - Optional. The value to assign to thecoFE-Custom-Configurationheader value. Overrides the globalcustomHeaderValueoption set when configuring the SDK. -
serverOptions- ServerOptions - Optional for client-side configuration and required for server-side session management. Contains thereqobject of type IncomingMessage andresobject of type ServerResponse with cookies.
callAction method to call a custom extension customActions/getCustomerCoupons with a custom header, query, and payload to be executed in sequence.callAction method for custom actions. For commercetools extensions, you can use the sdk.composableCommerce integration to access the extensions which internally use callAction and already have the types and parameters completed.const response = await sdk.callAction<Customer>({
actionName: 'customActions/getCustomerCoupons',
payload: { customer: { email: 'username@example.com' } },
query: { customerId: '4' },
parallel: false,
customHeaderValue: '{"customerAuthId":9188377992}',
});
if (response.isError) {
setError(response.error);
} else {
setCustomer(response.data);
}
getPage
getPage method retrieves the page or redirect data for static and dynamic pages from the API hub. This method is primarily used to fetch the page data from the Studio and render the pages with the Frontend components. This method is used at the catch-all route packages/<projectName>/frontend/app/[locale]/[[...slug]]/page.tsx. This method accepts the following options:-
path- String - Required. The relative path of the page of which you want to fetch the data. For example,/saleor/home/best-sellers. -
query- Object - Optional. An object of key-value pairs to be serialized into the URL query parameters. It accepts the value types specified in AcceptedQueryTypes. -
customHeaderValue- String - Optional. The value to assign to thecoFE-Custom-Configurationheader value. Overrides the globalcustomHeaderValueoption set when configuring the SDK. -
serverOptions- ServerOptions - Optional for client-side configuration and required for server-side session management. Contains thereqobject of type IncomingMessage andresobject of type ServerResponse with cookies.
getPage method to get the /sale page information with a query and custom header:const response = await sdk.page.getPage({
path: '/sale',
query: { size: 'M' },
customHeaderValue: '{"customerAuthId":9188377992}',
});
if (response.isError) {
const router = useRouter();
router.push('/404');
} else {
setPageData(response.data);
}
getPreview
getPreview method retrieves the preview data for Studio page previews, used at packages/<projectName>/frontend/app/[locale]/preview/[previewId]/page.tsx. This method accepts the following options:-
previewId- String - Required. A string representing the ID of the preview to fetch. -
customHeaderValue- String - Optional. The value to assign to thecoFE-Custom-Configurationheader value. Overrides the globalcustomHeaderValueoption set when configuring the SDK. -
serverOptions- ServerOptions - Optional for client-side configuration and required for server-side session management. Contains thereqobject of type IncomingMessage andresobject of type ServerResponse with cookies.
getPreview method to get page preview data with the previewId and custom header:const response = await sdk.page.getPreview({
previewId: 'p9986b2d', // Replace this with the variable containing the previewId
customHeaderValue: '{"customerAuthId":9188377992}',
});
if (response.isError) {
handleError(response.error);
} else {
setPreviewData(response.data);
}
getPages
getPages method lets you fetch the page data for a page folder and all its sub-pages. This method is primarily used in B2C projects to generate the sitemap for static pages at packages/<projectName>/frontend/app/[locale]/sitemap-static.xml/route.ts. This method accepts the following options:-
path- String - Optional. Defaults to/. The relative path of the page of which you want to fetch the data. -
depth- Number - Optional. Defaults to16. The depth of the page folder tree up to which you want to fetch the data. -
types- String - Optional. Defaults tostatic. The types of pages to fetch. -
customHeaderValue- String - Optional. Defaults to an empty string. The value to assign to thecoFE-Custom-Configurationheader value. Overrides the globalcustomHeaderValueoption set when configuring the SDK. -
serverOptions- ServerOptions - Optional for client-side configuration and required for server-side session management. Contains thereqobject of type IncomingMessage andresobject of type ServerResponse with cookies.
getPages method to get the page data for all pages under the /sale hierarchy up to two levels deep. For example, /sale, /sale/shirts, /sale/shirts/special, and so on.const response = await sdk.page.getPages({
path: '/sale',
depth: 2,
customHeaderValue: '{"customerAuthId":9188377992}',
});
if (response.isError) {
handleError(response.error);
} else {
generateSitemap(response.data.pageFolderStructure);
}
Add SDK integrations
CommercetoolsSDK constructor and pass the SDK instance, such as the ComposableCommerce instance. For example://.... Other code
constructor() {
super();
// customIntegration is an example name here
this.customIntegration = new CustomIntegration(this);
}
//.... Other code
Additionally, any custom events must be added to the SDK generic type as a type intersection. For example:
class CommercetoolsSDK extends SDK<ComposableCommerceEvents & CustomIntegrationEvents> {
...
}
The backend actions must be added to your backend service to extend your extensions API.
The event engine
EventManager class, extended by the SDK. It is also possible to extend the event types with custom events with the generic argument passed from the SDK.Following is a description of the three methods available on the SDK to manage event handlers:
triggeris called to trigger an event, for which an instance of theEventclass from@comercetools/frontend-sdkis passed.
An event is constructed witheventNameanddata. TheeventNamecorresponds to the[key: string]value in@comercetools/frontend-sdk'sStandardEvents. In custom eventsdatacorresponds to the type of value set for the event.
For example, to trigger themarketingBannerClickedcustom event,triggeris called on thesdkand an event constructed witheventName: 'marketingBannerClicked'anddata: { id: "<string>" }is passed.onis called to add an event handler for an event. The method takes theeventNameandhandlerarguments.
For example, for themarketingBannerClickedcustom event,marketingBannerClickedis passed for theeventNameargument and a function witheventparameter of type{ data: { id: "<string>" } }is passed for thehandlerargument.offis called to remove an event handler. For example, to persist the handler only for the lifecycle of a particular component.
The function takes the same arguments as theonfunction. For it to work, a named function for thehandlerargument must be defined. To successfully pass a named function to thehandlerparameter, theeventtype in the function's argument must be fully typed, as shown in the following examples.
Events are likely to be triggered only during action calls. The integrations you use may also create handlers so they can communicate with other integrations. However, you must be careful to avoid infinite recursion by mistakenly triggering events from event handlers.
onclick and onchange.Create custom events handlers
The commercetools Frontend SDK lets you create custom events that you can trigger from within the application, such as when clicking on a particular component or holding the pointer over it.
By default, event triggers and handlers will exist for the website's lifetime. However, you may want some to exist only during the lifetime of a specific React component. In that case, you must remove the event handlers on component unmounts. Otherwise, events can stack up due to component unmounting and remounting and may attempt to perform state updates on unmounted components, depending on the nature of the custom events.
MarketingBanner component and you want to track how many times the banner image is clicked using the marketingBannerClicked event. To achieve this behavior, the MarketingBanner component can use the onClick React event handler, which triggers the marketingBannerClicked event.To add custom event triggers to the SDK event definition, follow these steps:
-
Create a
MyCustomEvents.tsfile in thepackages/PROJECT_NAME/frontend/sdkfolder with the following content:// packages/PROJECT_NAME/frontend/sdk/MyCustomEvents.ts export type MyCustomEvents = { marketingBannerClicked: { id: string }; }; -
Add the type you created to the
CommercetoolsSDKclass in the generic SDK argument. The type must be added in the form of an intersection, as shown in the following example:// packages/PROJECT_NAME/frontend/sdk/CommercetoolsSDK.ts import { SDK } from "@commercetools/frontend-sdk"; import { ComposableCommerce, ComposableCommerceEvents } from "@commercetools/frontend-composable-commerce"; import { MyCustomEvents } from "./MyCustomEvents"; class CommercetoolsSDK extends SDK<ComposableCommerceEvents & MyCustomEvents> { ... } ... -
Implement the
MarketingBannerReact component. In this example, we're making a simple banner component with an image.import Image from 'next/image'; import { useEffect } from 'react'; import { sdk } from '../../sdk'; import { Event } from '@commercetools/frontend-sdk'; interface Props { marketingId: string; imageSrc: string; } const MarketingBanner = ({ marketingId, imageSrc }: Props) => { const marketingBannerClickedHandler = ( event: Event< 'marketingBannerClicked', { id: string; } > ) => { // Perform custom event handling logic here. console.log('Marketing banner clicked, id: ' + event.data.id); }; const clickHandler = (id: string) => { sdk.trigger( new Event({ eventName: 'marketingBannerClicked', data: { id: id, }, }) ); }; useEffect(() => { sdk.on('marketingBannerClicked', marketingBannerClickedHandler); return () => { sdk.off('marketingBannerClicked', marketingBannerClickedHandler); }; }, []); return <Image src={imageSrc} onClick={() => clickHandler(marketingId)} />; }; export default MarketingBanner;We define a function namedmarketingBannerClickedHandlerthat takes a parametereventof classEventfrom the@commercetools/frontend-sdklibrary. This class takes theEventNameandEventDataparameters as the generic arguments, matching the event we defined earlier in theMyCustomEvents.tsfile by name (key) and data (value) respectively.Then, we define a functionclickHandlerthat constructs themarketingBannerClickedevent and triggers it using thesdk.triggermethod. The event has the following properties:eventName: the name of the custom event.data: value of the custom event whereidis the identifier of the clicked marketing banner.
Then, we use the ReactuseEffecthook to callsdk.onto set up the event handler on component mount andsdk.offto remove the handler on component unmount by passing the named handler on both occasions.Finally we call theclickHandlerfrom theonClickevent of theImagecomponent.