# Using version 1 of the Frontend SDK Learn about using various features of version 1 of the Frontend SDK. We recommend using [version 2](/frontend-development/using-the-frontend-sdk.md) of the SDK to get the newest features, improvements, and fixes. ## Configure the SDK The `configure` method is defined on the [base SDK main class](https://github.com/FrontasticGmbH/frontend-sdk/blob/master/src/library/SDK.ts) 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-DE` or `en_DE`. In your code, you can access the `locale` from the `PageProps.params.locale` (Next.js 12) or using the `useParams()` hook (Next.js 13). - `currency` - String - Required. The three-letter [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) Currency Code. For example, `EUR`. For more information, see [supported currencies](https://github.com/FrontasticGmbH/frontend-sdk/blob/master/src/types/Currency.ts). - `endpoint` - String - Required. The full URL of the API hub endpoint. - `extensionVersion` - String - Required. The extension bundle version to connect to. - `useCurrencyInLocale` - Boolean - Optional. If `true`, the currency is required in the `locale` in the format `LOCALE@CURRENCY`. Defaults to `false`. Overrides the `currency` option. - `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](https://github.com/FrontasticGmbH/frontend-sdk/blob/master/src/constants/defaultSessionLifetime.ts) of three months. - `customHeaderValue` - String - Optional. This is the value sent as the `coFE-Custom-Configuration` header value with every request. You can override this value on a specific request by setting the `customHeaderValue` option in the [API methods](/frontend-development/using-the-frontend-sdk.md#api-methods). To access this value globally, call the `SDK.customHeaderValue()` function. - `cookieHandlingOverride` - [CookieManager](https://github.com/FrontasticGmbH/frontend-sdk/blob/master/src/types/cookieHandling/CookieManager.ts) - Optional. This option gives the user the ability to extend or override the default base SDK's [CookieHandler](https://github.com/FrontasticGmbH/frontend-sdk/blob/master/src/library/CookieHandler.ts). The following code example shows how to extend the default cookie handling using the `defaultConfigure` method in the [SDK template file](/frontend-development/frontend-sdk.md#sdk-template-file). ```ts title="Example code to specify custom cookie handling logic" 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); }, }, }); ``` ## API methods The base SDK provides various methods to interact with the backend extensions API. We recommend using the SDK methods for backend extension requests because the base SDK lets you [configure](/frontend-development/installing-the-frontend-sdk.md#install-the-sdk) options such as the locale, currency, endpoint, and extension version, and it maintains these throughout your application. All API methods return the [SDKResponse](https://github.com/FrontasticGmbH/frontend-sdk/tree/1.13.2/src/types/SDKResponse.ts) type, which has an `isError` boolean property that you can use for [narrowing](https://www.typescriptlang.org/docs/handbook/2/narrowing.html). 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. ### callAction The `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](https://github.com/FrontasticGmbH/frontend-sdk/tree/1.13.2/src/types/SDKResponse.ts) of a successful request. It also accepts the following options: - `actionName` - String - Required. The name of the action extension to call. For example, use `product/getProduct` to call the following extension: `{ actions: { product: { getProduct: (...) => { ... } } } }`. - `payload` - Object - Optional. A payload object with key-value pairs to be serialized into the request body. - `query` - Object - Optional. An object of key-value pairs to be serialized into the request query parameters. It accepts the value types specified in [AcceptedQueryTypes](https://github.com/FrontasticGmbH/frontend-sdk/tree/1.13.2/src/types/Query.ts). - `skipQueue` - Boolean - Optional. Defaults to `false`. Set to `true` to skip the action queue and execute fully asynchronously. May cause race conditions if used incorrectly. - `customHeaderValue` - String - Optional. The value to assign to the `coFE-Custom-Configuration` header value. Overrides the global `customHeaderValue` option set when [configuring](/frontend-development/using-the-frontend-sdk.md#configure-the-sdk) the SDK. - `serverOptions` - [ServerOptions](https://github.com/FrontasticGmbH/frontend-sdk/tree/1.13.2/src/types/cookieHandling/ServerOptions.ts) - Optional for client-side configuration and required for server-side session management. Contains the `req` object of type [IncomingMessage](https://nodejs.org/docs/latest-v18.x/api/http.html#class-httpincomingmessage) and `res` object of type [ServerResponse](https://nodejs.org/docs/latest-v18.x/api/http.html#class-httpserverresponse) with cookies. By default all actions are added to a queue and executed synchronously to avoid potential race conditions. You can change the default behavior by using the `skipQueue` option. The following code example uses the `callAction` method to call a custom extension `customActions/getCustomerCoupons` with a custom header, query, and payload. You only need to use the `callAction` method for custom actions. For commercetools extensions, you can use the `sdk.composableCommerce` integration to access the extensions. ```ts title="Example of the callAction method to get customer's coupon information" const response = await sdk.callAction({ actionName: 'customActions/getCustomerCoupons', payload: { customer: { email: 'username@example.com' } }, query: { customerId: '4' }, skipQueue: true, customHeaderValue: '{"customerAuthId":9188377992}', }); if (response.isError) { setError(response.error); } else { setCustomer(response.data); } ``` ### getPage The `getPage` method retrieves the page 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//frontend/app/[locale]/[[...slug]]/page.tsx`](https://github.com/FrontasticGmbH/components/tree/1.17.0/app/%5Blocale%5D/%5B%5B...slug%5D%5D/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, `/sale` or `/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](https://github.com/FrontasticGmbH/frontend-sdk/tree/1.13.2/src/types/Query.ts). - `customHeaderValue` - String - Optional. The value to assign to the `coFE-Custom-Configuration` header value. Overrides the global `customHeaderValue` option set when [configuring](/frontend-development/using-the-frontend-sdk.md#configure-the-sdk) the SDK. - `serverOptions` - [ServerOptions](https://github.com/FrontasticGmbH/frontend-sdk/tree/1.13.2/src/types/cookieHandling/ServerOptions.ts) - Optional for client-side configuration and required for server-side session management. Contains the `req` object of type [IncomingMessage](https://nodejs.org/docs/latest-v18.x/api/http.html#class-httpincomingmessage) and `res` object of type [ServerResponse](https://nodejs.org/docs/latest-v18.x/api/http.html#class-httpserverresponse) with cookies. The following code example uses the `getPage` method to get the `/sale` page information with a query and custom header: ```ts title="Example of the getPage method to get page data" 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 The `getPreview` method retrieves the preview data for Studio page previews, used at [`packages//frontend/app/[locale]/preview/[previewId]/page.tsx`](https://github.com/FrontasticGmbH/components/tree/1.17.0/app/%5Blocale%5D/preview/%5BpreviewId%5D/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 the `coFE-Custom-Configuration` header value. Overrides the global `customHeaderValue` option set when [configuring](/frontend-development/using-the-frontend-sdk.md#configure-the-sdk) the SDK. - `serverOptions` - [ServerOptions](https://github.com/FrontasticGmbH/frontend-sdk/tree/1.13.2/src/types/cookieHandling/ServerOptions.ts) - Optional for client-side configuration and required for server-side session management. Contains the `req` object of type [IncomingMessage](https://nodejs.org/docs/latest-v18.x/api/http.html#class-httpincomingmessage) and `res` object of type [ServerResponse](https://nodejs.org/docs/latest-v18.x/api/http.html#class-httpserverresponse) with cookies. The following code example uses the `getPreview` method to get page preview data with the `previewId` and custom header: ```ts title="Example of the getPreview method to get page preview data" 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 The `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//frontend/app/[locale]/sitemap-static.xml/route.ts`](https://github.com/FrontasticGmbH/components/tree/1.17.0/app/%5Blocale%5D/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 to `16`. The depth of the page folder tree up to which you want to fetch the data. - `types` - String - Optional. Defaults to `static`. The types of pages to fetch. - `customHeaderValue` - String - Optional. Defaults to an empty string. The value to assign to the `coFE-Custom-Configuration` header value. Overrides the global `customHeaderValue` option set when [configuring](/frontend-development/using-the-frontend-sdk.md#configure-the-sdk) the SDK. - `serverOptions` - [ServerOptions](https://github.com/FrontasticGmbH/frontend-sdk/tree/1.13.2/src/types/cookieHandling/ServerOptions.ts) - Optional for client-side configuration and required for server-side session management. Contains the `req` object of type [IncomingMessage](https://nodejs.org/docs/latest-v18.x/api/http.html#class-httpincomingmessage) and `res` object of type [ServerResponse](https://nodejs.org/docs/latest-v18.x/api/http.html#class-httpserverresponse) with cookies. The following code example uses the `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. ```ts title="Example of the getPages method to get page data for multiple pages" 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 It is possible to extend the SDK with the [integrations you develop](/frontend-development/developing-sdk-integrations-v1.md). To do so, set up the integrations in the `CommercetoolsSDK` constructor and pass the SDK instance, such as the `ComposableCommerce` instance. For example: ```ts title="Initialize an integration in the SDK" //.... 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: ```ts title="Add custom integration events type using intersection" class CommercetoolsSDK extends SDK { ... } ``` The backend actions must be added to your backend service to extend your extensions API. ## The event engine The commercetools Frontend SDK comes with event management tools to let integrations communicate with other integrations and the user of the integration to add or create an event handler. The source for this functionality is the [`EventManager`](https://github.com/FrontasticGmbH/frontend-sdk/tree/1.13.2/src/library/EventManager.ts) 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: - `trigger` is called to trigger an event, for which an instance of the [`Event`](https://github.com/FrontasticGmbH/frontend-sdk/tree/1.13.2/src/library/Event.ts) class from `@comercetools/frontend-sdk` is passed. An event is constructed with `eventName` and `data`. The `eventName` corresponds to the `[key: string]` value in `@comercetools/frontend-sdk`'s `StandardEvents`. In custom events `data` corresponds to the type of value set for the event. For example, to trigger the `marketingBannerClicked` custom event, `trigger` is called on the `sdk` and an event constructed with `eventName: 'marketingBannerClicked'` and `data: { id: "" }` is passed. - `on` is called to add an event handler for an event. The method takes the `eventName` and `handler` arguments. For example, for the `marketingBannerClicked` custom event, `marketingBannerClicked` is passed for the `eventName` argument and a function with `event` parameter of type `{ data: { id: "" } }` is passed for the `handler` argument. - `off` is 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 the `on` function. For it to work, a named function for the `handler` argument must be defined. To successfully pass a named function to the `handler` parameter, the `event` type 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. The SDK event engine should only be used for events specific to the base SDK and integrations. The standard [React events](https://react.dev/learn/responding-to-events) should be used for component events such as `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. To understand event handlers better, let's suppose you have a `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: 1. Create a `MyCustomEvents.ts` file in the `packages/PROJECT_NAME/frontend/sdk` folder with the following content: ```ts title="Custom events type definition" // packages/PROJECT_NAME/frontend/sdk/MyCustomEvents.ts export type MyCustomEvents = { marketingBannerClicked: { id: string }; }; ``` 2. Add the type you created to the `CommercetoolsSDK` class in the generic SDK argument. The type must be added in the form of an intersection, as shown in the following example: ```ts title="Extend the base SDK type with custom events type" // 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 { ... } ... ``` 3. Implement the `MarketingBanner` React component. In this example, we're making a simple banner component with an image. ```tsx title="MarketingBanner React component implementation with event handlers" 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 clickHandler(marketingId)} />; }; export default MarketingBanner; ``` We define a function named `marketingBannerClickedHandler` that takes a parameter `event` of class [`Event`](https://github.com/FrontasticGmbH/frontend-sdk/tree/1.13.2/src/library/Event.ts) from the `@commercetools/frontend-sdk` library. This class takes the `EventName` and `EventData` parameters as the generic arguments, matching the event we defined earlier in the `MyCustomEvents.ts` file by name (key) and data (value) respectively. Then, we define a function `clickHandler` that constructs the `marketingBannerClicked` event and triggers it using the `sdk.trigger` method. The event has the following properties: - `eventName`: the name of the custom event. - `data`: value of the custom event where `id` is the identifier of the clicked marketing banner. Then, we use the React [`useEffect`](https://react.dev/reference/react/useEffect) hook to call `sdk.on` to set up the event handler on component mount and `sdk.off` to remove the handler on component unmount by passing the named handler on both occasions. Finally we call the `clickHandler` from the `onClick` event of the `Image` component. For more information about how you can extend the SDK with integrations, see [Developing SDK integrations](/frontend-development/developing-sdk-integrations-v1.md). ## Related pages - [Area overview page with navigation](/frontend-development.md) - [Previous page: Overview](/frontend-development/frontend-sdk-v1.md) - [Next page: Developing SDK integrations](/frontend-development/developing-sdk-integrations-v1.md) - [Search documentation and API specs](/search.md)