Utilising SDK modules
Introduction
Alokai SDK is a framework-agnostic communication layer in Alokai Integrations. It communicates with Commerce Platforms and third-party services through the Server Middleware, which works as a proxy. Alokai SDK creates a contract between the storefront and the Server Middleware.
The middlewareModule
is a module of the Alokai SDK that allows you to interact with the Storefront API. It is designed to work seamlessly with other Alokai SDK modules, such as those for various eCommerce platforms like SAP Commerce Cloud.
In this guide, we'll show you how to use the SDK modules in your Storefront application.
Installation
To use a new module, for instance the SAP Commerce Cloud, you'll need to follow the below steps:
Installing the middleware API module
Remember that each time you add an SDK module, it should have a relevant middleware API Client installed as well. In Storefront, the middleware API Client should be installed into the apps/storefront-middleware
directory.
- Install the API Client (the server).
yarn workspace storefront-middleware add @vsf-enterprise/sapcc-api
- Update
apps/storefront-middleware/middleware.config.ts
file.
- Add new API-client integration to the config (more info here)
// apps/storefront-middleware/middleware.config.ts
const config = {
integrations: {
...,
sapcc: {
location: '@vsf-enterprise/sapcc-api/server',
configuration: {
OAuth: {
uri: process.env.SAPCC_OAUTH_URI,
clientId: process.env.SAPCC_OAUTH_CLIENT_ID,
clientSecret: process.env.SAPCC_OAUTH_CLIENT_SECRET,
tokenEndpoint: process.env.SAPCC_OAUTH_TOKEN_ENDPOINT,
tokenRevokeEndpoint: process.env.SAPCC_OAUTH_TOKEN_REVOKE_ENDPOINT,
cookieOptions: {
'vsf-sap-token': { secure: process.env.NODE_ENV !== 'development' }
}
},
api: {
uri: process.env.SAPCC_API_URI,
baseSiteId: 'apparel-uk',
catalogId: 'apparelProductCatalog',
catalogVersion: 'Online',
defaultLanguage: 'en',
defaultCurrency: 'GBP'
},
}
}
},
};
- Export the API Client
Endpoints
type fromstorefront-middleware/types.ts
file.
export type { Endpoints as SapccEndpoints } from "@vsf-enterprise/sapcc-api";
- Update SDK config.
- Add the new module inside SDK configuration.
// apps/storefront-unified-nextjs/sdk/config.ts
import { SapccEndpoints } from "storefront-middleware/types"; import { defineSdkConfig } from '@vue-storefront/next';
export function getSdkConfig() {
return defineSdkConfig(({ buildModule, config, getRequestHeaders, middlewareModule }) => ({
// ...
sapcc: buildModule(middlewareModule<SapccEndpoints>, {
apiUrl: `${config.middlewareUrl}/sapcc`,
defaultRequestConfig: {
headers: getRequestHeaders(),
},
}),
}));
}
Now you can use both sdk.unified.<methodName>
, which returns the Unified Data Model, and sdk.sapcc.<methodName>
which returns the raw data.
Real World Examples
Adding Product Reviews with SAP SDK
In this example, we'll create a custom React hook that utilizes useQuery and sdk.sapcc.createProductReview
to add product reviews. We'll also create a form component for adding reviews and update the existing ProductReviews
component to include the form.
Creating the useAddProductReview Hook
- Create a new file
useAddProductReview.ts
in ahooks/
directory. - Import the necessary dependencies, including the
useQuery
hook and the SAP SDK module. - Implement the
useAddProductReview()
hook to utilize useQuery and thesdk.sapcc.createProductReview
method to add a product review. - Return the necessary variables and functions from the hook.
import { useMutation } from "@tanstack/react-query";
import { sdk } from "~/sdk";
export const useAddProductReview = (productCode: string) => {
return useMutation(["addProductReview", productCode], ({ review }) =>
sdk.sapcc.createProductReview({ productCode, review })
);
};
Update the index.ts
in the hooks/
directory and export useAddProductReview
module:
export * from "./useAddProductReview";
Creating the AddProductReviewForm Component
- Create a new client component
add-product-review-form.tsx
in thecomponents/
directory. - Import the necessary React components from the
@storefront-ui
library (e.g.,SfInput
,SfTextarea
). - Import the
useAddProductReview
hook. - Define the
AddProductReviewForm
component as a client component. - Implement the form submission handler function that will utilize the
createProductReview
function from theuseAddProductReview
hook. - Render the form fields and UI components using SFUI library.
- Export the
AddProductReviewForm
component for use in other components.
"use client";
import {
SfButton,
SfInput,
SfTextarea,
SfRatingButton,
} from "@storefront-ui/react";
import { resolveFormData } from "@/helpers/form-data";
import useAddProductReview from "@/hooks";
interface AddProductReviewFormProps {
productId: string;
}
export function AddProductReviewForm({ productId }: AddProductReviewFormProps) {
const createProductReview = useAddProductReview(productId);
const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {
event.preventDefault();
createProductReview.mutate(
{ review: resolveFormData(event.currentTarget) },
{
onSuccess() {
// Handle success
console.log("Product review submitted successfully");
},
onError() {
// Handle error
console.error("Failed to submit product review:", error);
},
}
);
};
return (
<form onSubmit={handleSubmit} className="space-y-5 mx-3">
<h3 className="my-3">Write a Review</h3>
<div>
<p id="rating">Select Rating</p>
<SfRatingButton name="rating" aria-labelledby="rating" />
</div>
<div>
<label htmlFor="title">Title:</label>
<SfInput id="title" type="text" name="title" required />
</div>
<div>
<label htmlFor="review" className="block">
Review:
</label>
<SfTextarea id="review" name="review" required />
</div>
<SfButton type="submit">Submit Review</SfButton>
</form>
);
}
Updating the ProductReviews Component
- Import the
AddProductReviewForm
component into the existingProductReviews
component. - Add the
AddProductReviewForm
component to the JSX of theProductReviews
component.
"use client";
// Some of the imports was omitted for brevity
import { useTranslations } from "next-intl";
import { useQuery } from "@tanstack/react-query";
import { useSdk } from "@/sdk/sdk-context";
import Review from "./ui/review";
import AddProductReviewForm from "./add-product-review-form";
interface ProductReviewsProps {
productId: string;
}
export function ProductReviews({ productId }: ProductReviewsProps) {
// ... Some code was omitted for brevity
const t = useTranslations("ProductReviews");
const sdk = useSdk();
const reviews = useQuery({
queryFn: () => sdk.unified.getProductReviews({ productId }),
// ...
});
return (
<>
{/* Existing code for displaying product reviews */}
{reviewsList.map((review) => (
<Review
key={review.id}
content={review.text}
author={review.reviewer}
title={review.title}
rating={review.rating}
date={review.createdAt}
showLessText={t("readLess")}
showMoreText={t("readMore")}
/>
))}
{/* Add product review form */}
<AddProductReviewForm productId={productId} />
</>
);
}