Alokai
You are reading the documentation for connect v1, which is no longer the latest version. Switch to connect v2

Getting Started

If you're setting your Alokai application from scratch, you'll need to configure a type-safe SDK that communicates with your Server Middleware.

In the examples below, we assume that you have an Alokai app with the Unified Data Model. However, the approach for non-unified Alokai applications is similar.

There are various ways to configure the SDK, depending on your chosen framework. For Next.js and Nuxt, you can use the @vue-storefront/next and @vue-storefront/nuxt packages respectively. These packages also provide tools for handling the global state management.

If you're looking for framework agnostic experience, you can use the @alokai/connect package. The sdk package is a part of the @alokai/connect package and provides the core functionality of the SDK.

Installation

To get started with the SDK within Next.js, first you have to install the @vue-storefront/next package. In the root of your Storefront project run:

Next.js
# Using yarn
yarn add --dev @vue-storefront/next

# Using pnpm
pnpm add -D @vue-storefront/next

# Using npm
npm install --save-dev @vue-storefront/next

Initializing the SDK

To use SDK in our application, we need to initialize it first. To do so, follow these steps:

  1. Create an sdk directory in the root of your project.

  2. Create the SDK Options file — sdk.options.ts in the sdk directory. In this file, we create a configuration object used to pass information to the SDK Factory about the address of the middleware, both in client and SSR mode, the identifier for cache busting, etc.

If you want to keep your Storefront more configurable, we highly recommend using the next-runtime-env library to read the environment variables from the runtime rather than hard-coding them during the build process.

sdk/options.ts
import { resolveSdkOptions } from "@vue-storefront/next";
import { env } from "next-runtime-env";

export function getSdkOptions() {
  const apiUrl = env("NEXT_PUBLIC_ALOKAI_MIDDLEWARE_API_URL") ?? "";
  const ssrApiUrl = env("NEXT_PUBLIC_ALOKAI_MIDDLEWARE_SSR_API_URL");
  const cdnCacheBustingId =
    env("NEXT_PUBLIC_ALOKAI_MIDDLEWARE_CDN_CACHE_BUSTING_ID") ??
    "no-cache-busting-id-set";
  const isMultiStoreEnabled =
    env("NEXT_PUBLIC_ALOKAI_MULTISTORE_ENABLED") === "true";

  if (!apiUrl) {
    throw new Error(
      "NEXT_PUBLIC_ALOKAI_MIDDLEWARE_API_URL is required to run the app"
    );
  }

  if (!ssrApiUrl) {
    throw new Error(
      "NEXT_PUBLIC_ALOKAI_MIDDLEWARE_SSR_API_URL is required to run the app"
    );
  }

  const options = resolveSdkOptions({
    middleware: {
      apiUrl,
      cdnCacheBustingId,
      ssrApiUrl,
    },
    multistore: {
      enabled: isMultiStoreEnabled,
    },
  });

  return options;
}
  1. Create SDK Config file - config.ts. In this file, we define the configuration of different modules. We are making it a separate file to easily import it both on the server and the client. Create the SDK configuration by importing the defineSdkConfig function from the Next.js SDK and importing modules from a dedicated modules directory.
sdk/config.ts
import { defineSdkConfig } from "@vue-storefront/next";

import * as modules from './modules';

export function getSdkConfig() {
  return defineSdkConfig(modules);
}

Each module should be defined in a separate file under the sdk/modules directory. Here's an example of how you can structure your modules:

sdk/modules/commerce.ts
import { defineSdkModule } from '@vue-storefront/next';
import type { CommerceEndpoints } from "storefront-middleware/types";

export const commerce = defineSdkModule(({ buildModule, config, getRequestHeaders, middlewareModule }) =>
  buildModule(middlewareModule<CommerceEndpoints>, {
    apiUrl: `${config.apiUrl}/commerce`,
    cdnCacheBustingId: config.cdnCacheBustingId,
    defaultRequestConfig: {
      headers: getRequestHeaders(),
    },
    ssrApiUrl: `${config.ssrApiUrl}/commerce`,
  }),
);
sdk/modules/cms.ts
import { defineSdkModule } from '@vue-storefront/next';
import { contentfulModule } from "@vsf-enterprise/contentful-sdk";

export const cms = defineSdkModule(({ buildModule, config }) => 
  buildModule(contentfulModule, {
    apiUrl: `${config.apiUrl}/cms`,
    cdnCacheBustingId: config.cdnCacheBustingId,
    defaultRequestConfig: {
      headers: getRequestHeaders(),
    },
    ssrApiUrl: `${config.ssrApiUrl}/cms`,
  }),
);
sdk/modules/index.ts
export * from './commerce';
export * from './cms';

Let's break down the key concepts used in the module configuration:

  • The defineSdkModule function is a utility that helps define type-safe SDK modules. It takes a factory function that receives the SDK context and returns a module configuration. This ensures proper typing and provides better development experience.

  • The buildModule function is used to build the module. It expects the module and the module configuration as arguments.

  • The config is object containing data that is needed in module configuration such as:

    • apiUrl: The URL of the middleware instance for client-side requests
    • ssrApiUrl: The URL of the middleware instance for server-side requests
    • cdnCacheBustingId: The identifier for cache busting
  • The middlewareModule is an SDK module that ensures communication with the Server Middleware. It takes the UnifiedEndpoints type as a generic parameter. The UnifiedEndpoints type is a type that represents the endpoints of the Server Middleware.

  • The getRequestHeaders function is used to provide the incoming headers within your requests. You can use getRequestHeaders to access and proxy the initial cookie headers to SDK requests during SSR. Initial headers could be provided by the getSdk method. Check out examples there:

In the browser, getRequestHeaders will return an empty object.

  • The defineSdkConfig function returns the factory function for the SDK configuration as a second argument in createSdk. This factory function receives context, which is useful for creating the SDK configuration.
  1. Create SDK instance for server components. Let's do it in the sdk.server.ts in the sdk directory.

It is not necessary to name the file sdk.server.ts specifically or to keep it in the sdk directory, but it is recommended to keep it consistent with the rest of the Alokai project.

sdk/sdk.server.ts
import { createSdk } from "@vue-storefront/next";
import { getSdkOptions } from "./options";
import { getSdkConfig } from "./config";

export const { getSdk } = createSdk(getSdkOptions(), getSdkConfig());

export type Sdk = ReturnType<typeof getSdk>;

Let's break down the code above:

  • The createSdk function expects

    • base SDK options including the middleware and (optionally) the multistore configuration as a first argument,
    • and a factory function for the SDK configuration as a second argument. Those factory function receives a context, useful for creating the SDK configuration.
  • The createSdk function returns the getSdk function, which is used to retreive the new SDK instance.

Registering the SDK

Once you have initialized the SDK, you can register it in your application.

Alokai SDK can be used in two ways:

  • getSdk - returns the SDK instance, which can be used to call the SDK methods directly. This is useful for server-side rendering, as it allows you to call the SDK methods directly in your application.

  • createSdkContext - returns the SDK context, which can be used to share the same SDK instance on the Client side. This is useful for client-side rendering, as it allows you to share the same SDK instance across your application.

getSdk

getSdk is used to create the new SDK instance. This is especially useful for server-side fetching, as it returns a new SDK instance that can be used to call the SDK methods directly in your application.

Below is an example of how you can use getSdk in your application:

import { getSdk } from "@/sdk/sdk.server";

const sdk = await getSdk();

createAlokaiContext

For client-side rendering, you can use createAlokaiContext. This function serves for two purposes:

  • providing the SDK context
  • providing the global state management context and hooks for handling the state of the application

To use it, you'll need to create a new file in your application, for example sdk/alokai-context.tsx:

"use client";

import { createAlokaiContext } from "@vue-storefront/next/client";
import type { SfContract } from "storefront-middleware/types";

import type { Sdk } from "./sdk.server";

export const {
  AlokaiProvider,
  useSdk,
  useSfCartState,
  useSfCurrenciesState,
  useSfCurrencyState,
  useSfCustomerState,
  useSfLocaleState,
  useSfLocalesState,
} = createAlokaiContext<Sdk, SfContract>();

The SfContract interface is used to define the contract between the SDK and the state management. It contains the types for:

  • cart (SfCart type)
  • customer (SfCurrency type)
  • currency (SfCurrency type)
  • locale (SfLocale type)

This is needed to ensure that the state management is aware of the types that you have within the middleware, as those types can be changed within the middleware.

You can read more about the state management in the State Management page.

Once you have created the Alokai context, you can create client-side SDK instance and register it in your application.

You can do it in two steps:

  1. Retrieve the SDK config in the server component in app/[locale]/layout.tsx:
// app/[locale]/layout.tsx

import { ReactNode } from "react";
import { PublicEnvProvider } from "next-runtime-env";
import { Providers } from "./providers";
import { getSdkOptions } from "@/sdk/options";

export default function RootLayout({ children }: { children: ReactNode }) {
  const sdkOptions = getSdkOptions();

  return (
    <html lang="en">
      <body>
        <PublicEnvProvider>
          <Providers sdkOptions={sdkOptions}>{children}</Providers>
        </PublicEnvProvider>
      </body>
    </html>
  );
}
  1. Pass the SDK options to the Providers client component and initialize the SDK instance along with the AlokaiProvider:
// components/providers.tsx

"use client";

import { ReactNode } from "react";
import type { CreateSdkOptions } from "@vue-storefront/next";
import { SdkProvider } from "@/sdk";
import { getSdkOptions } from "@/sdk/options";
import { getSdkConfig } from "@/sdk/config";

export function Providers({
  children,
  sdkOptions,
}: {
  children: ReactNode;
  sdkOptions: CreateSdkOptions;
}) {
  const { getSdk } = createSdk(sdkOptions, getSdkConfig());
  return <AlokaiProvider sdk={getSdk()}>{children}</AlokaiProvider>;
}

Don't be alarmed if you see a use client directive in the components/providers.tsx file. This will not turn your application into a client-side rendered application. All children inside the provider will be still rendered on the server-side by default. You can read more about use client directive in React Documentation.

Usage

Once you have registered the SDK in your application, you can start using it. Here's an example of how you can use the SAP Commerce Cloud SDK module in your application:

import { getSdk } from "@/sdk";
import { getLocale } from 'next-intl/server';

export async function getServersideProps() {
  const sdk = await getSdk();
  const { products } = await sdk.commerce.searchProduct();

  return {
    props: {
      products,
    },
  };
}
import { getSdk } from "@/sdk";

const sdk = await getSdk();

const { products } = await sdk.commerce.searchProduct();
import { useEffect, useState } from "react";
import { useSdk } from "@/sdk/sdk-context";

export function ClientComponentUsingSDK() {
  const sdk = useSdk();
  const [cart, setCart] = useState([]);

  useEffect(() => {
    const fetchCart = async () => {
      const newCart = await sdk.commerce.getCart({
        cartId: "<cart_id>",
        fields: "code,guid,user(FULL)",
      });
      setCart(newCart);
    };

    fetchCart();
  }, []);
}

Code above is just an example of how you can use the SDK in your application. For more information about the available methods, please refer to the respective Integration's documentation.

That's it! You can now use VueStorefront SDK Module in your Next.js app ✨

Installation

To get started with the SDK within Nuxt, first you have to install and configure the @vue-storefront/nuxt module.

  1. In the root of your Storefront project run:
Nuxt
# Using yarn
yarn add --dev @vue-storefront/nuxt

# Using pnpm
pnpm add -D @vue-storefront/nuxt

# Using npm
npm install --save-dev @vue-storefront/nuxt
  1. Add @vue-storefront/nuxt to the modules section of nuxt.config.ts
nuxt.config.ts
export default defineNuxtConfig({
  modules: ["@vue-storefront/nuxt"],
});
  1. Configure the module

To configure the module, use vsf key in the Nuxt configuration object and provide necessary information such as the Middleware instance address:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ["@vue-storefront/nuxt"],
  vsf: {
    middleware: {
      apiUrl: "http://localhost:4000",
    },
  },
});

Initializing the SDK

To use SDK in our application, we need to initialize it first. To do so, follow these steps:

Create SDK Config file - sdk.config.ts in root directory of your project.

For Nuxt framework it's necessary to name the file sdk.config.ts and keep it in the root of your project.

You should import all SDK modules from a dedicated modules directory. Here's how to structure your Nuxt SDK configuration:

sdk.config.ts
import * as modules from './sdk-modules';

export default defineSdkConfig(modules);

Each module should be defined in a separate file under the sdk-modules directory:

sdk-modules/commerce.ts
import type { CommerceEndpoints } from 'storefront-middleware/types';

export const commerce = defineSdkModule(({ buildModule, config, getRequestHeaders, middlewareModule }) =>
  buildModule(middlewareModule<CommerceEndpoints>, {
    apiUrl: `${config.apiUrl}/commerce`,
    cdnCacheBustingId: config.cdnCacheBustingId,
    defaultRequestConfig: {
      headers: getRequestHeaders(),
    },
    ssrApiUrl: `${config.ssrApiUrl}/commerce`,
  }),
);
sdk-modules/cms.ts
import { contentfulModule } from "@vsf-enterprise/contentful-sdk";

export const cms = defineSdkModule(({ buildModule, config }) => 
  buildModule(contentfulModule, {
    apiUrl: `${config.apiUrl}/cms`,
    cdnCacheBustingId: config.cdnCacheBustingId,
    defaultRequestConfig: {
      headers: getRequestHeaders(),
    },
    ssrApiUrl: `${config.ssrApiUrl}/cms`,
  }),
);
sdk-modules/index.ts
export * from './commerce';
export * from './cms';

Let's break down the key concepts used in the Nuxt module configuration:

The defineSdkConfig function is used for initializing the SDK. The parameter for calling this function should be an anonymous function that receives an injected context from the module, containing:

  • the buildModule function,
  • the configuration object that contains data useful in module configuration such as: middleware URL (middlewareUrl), or cache busting identifier (cdnCacheBustingId)
  • the middlewareModule - an SDK module that ensures communication with the Server Middleware. It takes the UnifiedEndpoints type as a generic parameter. The UnifiedEndpoints type is a type that represents the endpoints of the Server Middleware,
  • a function for retrieving request header, including cookie header (getRequestHeaders).

Usage

Once you have initialized the SDK, you can start using it. Here's an example of how you can use the SAP Commerce Cloud SDK module in your application:

<template>/* ... */</template>

<script setup>
const sdk = useSdk();

const { data: products } = await useAsyncData("products", () =>
  sdk.commerce.searchProduct()
);
</script>

Code above is just an example of how you can use the SDK in your application. For more information about the available methods, please refer to the respective Integration's documentation.

That's it! You can now use VueStorefront SDK Module in your Nuxt app ✨

Installation

To install the SDK Core, run the following command:

# Using npm
npm install @alokai/connect

# Using yarn
yarn add @alokai/connect

# Using pnpm
pnpm install @alokai/connect

Initializing the SDK

Next, you have to initialize the SDK, along with any integrations' SDK modules in your frontend project. To do so, follow these steps:

  1. Create SDK Config file - sdk.config.ts in root directory of your project.

It is not necessary to name the file sdk.config.ts specifically or to keep it in the root of your project, but it is recommended to keep it consistent with the rest of the Alokai project.

  1. Create the SDK configuration by importing the initSDK function from the SDK Core and the modules you want to use.

The examples below use the SAP Commerce Cloud and Contentful SDK modules. However, the same principles apply to all modules.

When it comes to managing multiple SDK modules, there are two options for this:

  1. Individual exports (recommended) - initialize each integration as a separate SDK instance, allowing for better code-splitting
  2. Single Instance - combine multiple modules in one SDK instance

Individual Exports

sdk.config.ts
import { initSDK, buildModule, middlewareModule } from "@alokai/connect/sdk";
import { contentfulModule } from "@vsf-enterprise/contentful-sdk";
import { UnifiedEndpoints } from "storefront-middleware/types";

const { commerce } = initSDK({
  commerce: buildModule(middlewareModule<UnifiedEndpoints>, {
    apiUrl: "http://localhost:8181/commerce",
  }),
});

const { cms } = initSDK({
  cms: buildModule(contentfulModule, {
    apiUrl: "http://localhost:8181/cms",
  }),
});

export { commerce, cms };

Single Instance

sdk.config.ts
import { initSDK, buildModule, middlewareModule } from "@alokai/connect/sdk";
import { contentfulModule } from "@vsf-enterprise/contentful-sdk";
import { UnifiedEndpoints } from "storefront-middleware/types";

const sdkConfig = {
  commerce: buildModule(middlewareModule<UnifiedEndpoints>, {
    apiUrl: "http://localhost:8181/commerce",
  }),
  cms: buildModule(contentfulModule, {
    apiUrl: "http://localhost:8181/cms",
  }),
};

export const sdk = initSDK(sdkConfig);

The SDK Core exposes two methods to help with this, buildModules, which takes in SDK modules and uses them to extend the SDK Core, and initSDK, which takes multiple modules and converts them into a type-safe interface.

You can name the modules anything you want.

For example, you can rename commerce to sapcc and cms to contentful. initSDK will return an object with the same keys as the one passed to it.

Usage

Once you have initialized the SDK, you can start using it. Here's an example of how you can use the SAP Commerce Cloud SDK module in your application:

import { commerce } from "../sdk.config";

const { products } = await commerce.searchProduct();
import { sdk } from "../sdk.config";

const { products } = await sdk.commerce.searchProduct();

Code above is just an example of how you can use the SDK in your application. For more information about the available methods, please refer to the respective Integration's documentation.

That's it! You can now use VueStorefront SDK Module in any JavaScript app ✨

Next Steps

On this page