diff --git a/docs/content/4.sdk/1.index.md b/docs/content/4.sdk/1.index.md index 6770816d94..c32a63b23c 100644 --- a/docs/content/4.sdk/1.index.md +++ b/docs/content/4.sdk/1.index.md @@ -10,6 +10,10 @@ By utilizing the Alokai SDK, you can establish a type-safe contract between your :card{to="/sdk/getting-started" title="Get Started" description="Learn how to initialize the SDK in your storefronts" icon="ic:baseline-rocket"} +Along with the Alokai SDK, we're providing tools for the State Management. Those are already preconfigured and ready to use. Available both for Next.js and Nuxt through our dedicated packages. + +:card{to="/sdk/getting-started/state-management" title="State Management" description="Learn how to use built in State Manager" icon="grommet-icons:storage"} + ## Key Features diff --git a/docs/content/4.sdk/2.getting-started/1.index.md b/docs/content/4.sdk/2.getting-started/1.index.md index 6cc0381d49..519e9f7af0 100644 --- a/docs/content/4.sdk/2.getting-started/1.index.md +++ b/docs/content/4.sdk/2.getting-started/1.index.md @@ -6,7 +6,10 @@ If you're setting your Alokai application from scratch, you'll need to configure 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. If you're looking for framework agnostic experience, you can use the `@vue-storefront/sdk` package. +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 `@vue-storefront/sdk` package. ::tabs{:titles='["Next.js", "Nuxt", "Other"]' class="mt-8"} @@ -67,7 +70,7 @@ export function getSdkOptions() { } ``` -3. Create SDK Config file - `sdk.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 `createSdk` function from the Next.js SDK and using the `middlewareModule` it provides. You should also import other modules you want to use. +3. 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 `createSdk` function from the Next.js SDK and using the `middlewareModule` it provides. You should also import other modules you want to use. ```ts [sdk/config.ts] import { contentfulModule } from "@vsf-enterprise/contentful-sdk"; @@ -159,45 +162,35 @@ import { getSdk } from "@/sdk/sdk.server"; const sdk = getSdk(); ``` -### createSdkContext +### 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 -For client-side rendering, you can use `createSdkContext`. To use it, you'll need to create a new file in your application, for example `sdk/sdk-provider.tsx`: +To use it, you'll need to create a new file in your application, for example `sdk/alokai-context.tsx`: ```ts 'use client'; -import { createSdkContext } from '@vue-storefront/next/client'; +import { createAlokaiContext } from '@vue-storefront/next/client'; import type { Sdk } from './sdk.server'; -export const [SdkProvider, useSdk] = createSdkContext(); +export const { AlokaiProvider, useSdk } = createAlokaiContext(); ``` -Once you have created the SDK context, you can create client-side SDK instance and register it in your application. For example, if you're using the Pages Router, you can register it in `pages/_app.tsx`: +This is also a place where you can import hooks for handling the state management. You can read more about the state management in the [State Management](/sdk/getting-started/state-management) page. -```tsx -import type { AppProps } from "next/app"; -import { SdkProvider } from "@/sdk/sdk-provider"; -import { getSdkOptions } from "@/sdk/options"; -import { getSdkConfig } from "@/sdk/config"; +Once you have created the Alokai context, you can create client-side SDK instance and register it in your application. -export default function App({ Component, pageProps }: AppProps) { - const { getSdk } = createSdk( - getSdkOptions(), - getSdkConfig() - ); +You can do it in two steps: - return ( - - - - ); -} -``` +1. Retrieve the SDK config in the server component in `app/[locale]/layout.tsx`: -If you're using the App Router, you can register it in `app/layout.tsx`: +```tsx +// app/[locale]/layout.tsx -```tsx [app/layout.tsx] import { ReactNode } from "react"; import { PublicEnvProvider } from "next-runtime-env"; import { Providers } from "./providers"; @@ -218,7 +211,11 @@ export default function RootLayout({ children }: { children: ReactNode }) { } ``` -```tsx [app/providers.tsx] +2. Pass the SDK options to the `Providers` client component and initialize the SDK instance along with the `AlokaiProvider`: + +```tsx +// components/providers.tsx + "use client"; import { ReactNode } from "react"; @@ -232,13 +229,16 @@ export function Providers({ children, sdkOptions }: { children: ReactNode, sdkOp sdkOptions, getSdkConfig() ); - - return {children}; + return ( + + {children} + + ) } ``` ::info -Don't be alarmed if you see a `use client` directive in the `app/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](https://react.dev/reference/react/use-client). +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](https://react.dev/reference/react/use-client). :: ## Usage @@ -250,7 +250,7 @@ Once you have registered the SDK in your application, you can start using it. He ```tsx [Pages Router] import { getSdk } from "@/sdk"; -export function getServersideProps() { +export async function getServersideProps() { const sdk = getSdk(); const { products } = await sdk.commerce.searchProduct(); @@ -302,7 +302,7 @@ That's it! You can now use VueStorefront SDK Module in your Next.js app ✨ ## Installation -To get started with the SDK within Next.js, first you have to install and configure the `@vue-storefront/nuxt` module. +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: @@ -373,7 +373,7 @@ export default defineSdkConfig( Let's break down the code above: -The `defineSdkConfig` function is used for intializing the SDK. The parameter for calling this function should be an anonymous function that receives an injected context from the module, containing: +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`) @@ -396,7 +396,7 @@ const { data: products } = await useAsyncData("products", () => ``` -Code above is just an example of how you can use the SDK in your application. For more information about the avaialble methods, please refer to the respective [Integration's documentation](/integrations). +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](/integrations). That's it! You can now use VueStorefront SDK Module in your Nuxt app ✨ @@ -513,7 +513,7 @@ 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 avaialble methods, please refer to the respective [Integration's documentation](/integrations). +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](/integrations). That's it! You can now use VueStorefront SDK Module in any JavaScript app ✨ @@ -523,12 +523,14 @@ That's it! You can now use VueStorefront SDK Module in any JavaScript app ✨ ::grid{:columns="2"} #section-1 -:card{to="/sdk/advanced/extending-module" title="Extending the SDK" description="Learn how to customize, override, or extend any default functionality in the SDK" icon="ri:terminal-box-fill"} +:card{to="/sdk/getting-started/state-management" title="State Management" description="Learn how to use built in State Manager" icon="grommet-icons:storage"} #section-2 -:card{to="/sdk/advanced/middleware-module" title="The middlewareModule" description="Understand how to use the default SDK module" icon="fa6-solid:layer-group"} +:card{to="/sdk/advanced/extending-module" title="Extending the SDK" description="Learn how to customize, override, or extend any default functionality in the SDK" icon="ri:terminal-box-fill"} #section-3 -:card{to="/sdk/advanced/custom-modules" title="Create a custom SDK module" description="Create your own custom SDK module" icon="fluent:puzzle-cube-piece-20-filled"} +:card{to="/sdk/advanced/middleware-module" title="The middlewareModule" description="Understand how to use the default SDK module" icon="fa6-solid:layer-group"} #section-4 +:card{to="/sdk/advanced/custom-modules" title="Create a custom SDK module" description="Create your own custom SDK module" icon="fluent:puzzle-cube-piece-20-filled"} +#section-5 :card{to="/integrations" title="View all Integrations" description="View our ready-to-use integrations for popular e-commerce services" icon="fluent:puzzle-cube-piece-20-filled"} :: diff --git a/docs/content/4.sdk/2.getting-started/2.state-management.md b/docs/content/4.sdk/2.getting-started/2.state-management.md new file mode 100644 index 0000000000..6146d5a03b --- /dev/null +++ b/docs/content/4.sdk/2.getting-started/2.state-management.md @@ -0,0 +1,185 @@ +# State Management + +We offer ready-to-use tools for handling global state management tailored for both Next.js and Nuxt3 frameworks through our dedicated packages: `@vue-storefront/next` and `@vue-storefront/nuxt`. + +For Next.js, we utilize [Zustand](https://zustand.docs.pmnd.rs/), a small, fast, and scalable state-management solution. For Nuxt3, we leverage [Pinia](https://pinia.vuejs.org/), a state management library that is intuitive and integrates seamlessly with Vue 3. These tools are designed to simplify state management in your applications, providing robust and efficient solutions out of the box. + +Our state management solutions store core data such as: +- customer +- cart +- currently selected currency +- available currencies +- currently selected locale +- available locales + +They also provide methods for reading and updating this data, making it easy to manage and access global state across your application. + +::tabs{:titles='["Next.js", "Nuxt"]' class="mt-8"} + +#tab-1 + +## Installation + +To use the State Manager within Next.js, you need to have the `@vue-storefront/next` package installed. This step is already done if you have followed the [getting started](/sdk/getting-started). If not, you'll find installation instructions there. + +## Usage + +To use the state management, you need to extend the `alokai-context.tsx` file with the state management part. +All of the hooks that are returned from the `createAlokaiContext` function are straightforward to use. They follow the React's `useState` pattern, so you can read and write to the state like you would with the `useState`. + +```ts +// 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 } = createAlokaiContext(); // [!code --] +// [!code ++:11] +export const { + AlokaiProvider, + useSdk, + useSfCartState, + useSfCurrenciesState, + useSfCurrencyState, + useSfCustomerState, + useSfLocaleState, + useSfLocalesState, +} = createAlokaiContext(); +``` + +The `SfContract` interface is used to define the contract between the SDK and the state management. It contains the types for: +- cart +- customer +- currency +- locale + +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. + +## Initial data + +There is also an option to pass initial data to the `AlokaiProvider`. This can be useful when you want to set the initial state of the application. You can pass the initial currencies, currency, locale, and locales to the `AlokaiProvider`. To do this, you need to pass the `initialData` prop to the `AlokaiProvider` component. + +```tsx +// components/providers.tsx + +"use client"; + +import type { 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 ( + // [!code --] + // [!code ++:10] + + {children} + + ) +} +``` + +Note that the `Providers` component is a client component. If you want to fetch some data on the server side and pass it to the client component you can fetch the data in the server component (for Alokai Storefront it will be in the `app/[locale]/layout.tsx` file) and pass it to the client component through props. + + +## Usage + +The state is being updated on the Storefront side. State handling is already provided with the App Router based Alokai Storefront. You can use the state management in your components or hooks and modify the state as needed. +Here is an example of how you can use the state management in your components: + +```tsx +import { useQuery } from "@tanstack/react-query"; +import { + useSdk, + useSfCartState, + useSfCustomerState, + useSfCurrencyState, + useSfLocaleState, +} from "@/sdk/alokai-context"; + +function Component() { + const sdk = useSdk(); + const [cart, setCart] = useSfCartState(); + const [customer] = useSfCustomerState(); + const [currency] = useSfCurrencyState(); + const [locale] = useSfLocaleState(); + + const result = useQuery({ + queryFn: () => sdk.unified.getCart(), + queryKey: ["cart", "main"], + }); + // updating the cart state + useEffect(() => { + setCart(result.data); + }, [result.data]); + + return ( +
+

Cart total: {cart.total}

+

+ Customer name: {customer.firstName} {customer.lastName} +

+

Currency: {currency}

+

Locale: {locale}

+
+ ); +} +``` + +The same approach can be used in hooks or any other components. + +#tab-2 + +## Installation + +To use the State Manager within Nuxt, you need to have the `@vue-storefront/nuxt` package installed. This step is already done if you have followed the [getting started](/sdk/getting-started). If not, you'll find installation instructions there. + +## Usage + +To use it you don't need to do anything special. Just use the auto-imported `useSfState` composable in your components or composables. You can use parts of the state as refs so you can read and write to them easily. As mentioned before, the state is based on Pinia. To read more on how to use it, please refer to the [official documentation](https://pinia.vuejs.org/). + +Example usage of state management: + +```vue + + + +``` + +The same approach can be used in composables or any other components. + +:: diff --git a/docs/content/4.sdk/2.getting-started/2.middleware-module.md b/docs/content/4.sdk/2.getting-started/3.middleware-module.md similarity index 99% rename from docs/content/4.sdk/2.getting-started/2.middleware-module.md rename to docs/content/4.sdk/2.getting-started/3.middleware-module.md index 1f55fe5d62..f25b9bcf99 100644 --- a/docs/content/4.sdk/2.getting-started/2.middleware-module.md +++ b/docs/content/4.sdk/2.getting-started/3.middleware-module.md @@ -41,7 +41,7 @@ In Nuxt, `middlewareModule` is available in the `defineSdkConfig` function. import { UnifiedEndpoints } from "storefront-middleware/types"; export default defineSdkConfig( - ({ buildModule, config, middlewareModule getRequestHeaders }) => ({ + ({ buildModule, config, middlewareModule, getRequestHeaders }) => ({ commerce: buildModule(middlewareModule, { apiUrl: config.middlewareUrl + "/commerce", // SAP Commerce Cloud integration is available at /commerce endpoint defaultRequestConfig: { diff --git a/docs/content/guides/2.alokai-essentials/1.alokai-next-js/3.install-middleware.md b/docs/content/guides/2.alokai-essentials/1.alokai-next-js/3.install-middleware.md index 7464a907c4..24e18f7047 100644 --- a/docs/content/guides/2.alokai-essentials/1.alokai-next-js/3.install-middleware.md +++ b/docs/content/guides/2.alokai-essentials/1.alokai-next-js/3.install-middleware.md @@ -48,6 +48,11 @@ Now you can install the `@vsf-enterprise/sapcc-api` package by running the follo ```bash npm install @vsf-enterprise/sapcc-api ``` +You can also install the types by running the following command: + +```bash +npm install @vsf-enterprise/sapcc-types +``` ## Configure Alokai Middleware @@ -204,4 +209,4 @@ Let's install and configure the Alokai SDK in the Next.js application and learn :::docs-button{to="/guides/alokai-essentials/alokai-next-js/install-sdk"} Next ::: -:: \ No newline at end of file +:: diff --git a/docs/content/guides/2.alokai-essentials/1.alokai-next-js/4.install-sdk.md b/docs/content/guides/2.alokai-essentials/1.alokai-next-js/4.install-sdk.md index 9de48b4503..c3c9e37e6e 100644 --- a/docs/content/guides/2.alokai-essentials/1.alokai-next-js/4.install-sdk.md +++ b/docs/content/guides/2.alokai-essentials/1.alokai-next-js/4.install-sdk.md @@ -5,82 +5,105 @@ navigation: icon: tabler:number-3-small --- -# Install and Configure Alokai SDK +# Install and Configure Alokai Context -In the last sections, we have configured Alokai Next.js project and installed the Alokai Middleware. In this section, we will install and configure the Alokai SDK. +In the last sections, we have configured Alokai Next.js project and installed the Alokai Middleware. In this section, we will install and configure the Alokai Context that contains both the SDK and state manager. The Alokai SDK and Alokai Middleware together called Alokai Connect. Both SDK and Middleware are used in tandem to connect the Alokai frontend with the backend. SDK is responsible for establishing the connection with the Middleware, while Middleware is responsible to orchestrate the communication with the backend. -In this guide, we will install the Alokai SDK and configure it to work with SAP Commerce Cloud and Alokai Middleware. +The state manager is a built-in feature of the Alokai Context. It allows you to manage the state of your application in a more efficient way. It is based on the [Zustand](https://zustand-demo.pmnd.rs/) and provides a set of hooks to manage the state of your application. -## Install Alokai SDK +In this guide, we will install the Alokai Context and configure it to work with SAP Commerce Cloud and Alokai Middleware. -This time we will solely focus on `storefront` application. Navigate to a newly generated `storefront` directory and install the Next.js SDK package by running the following command: +## Install Alokai Context + +This time we will solely focus on `storefront` application. Navigate to a newly generated `storefront` directory and install the `@vue-storefront/next` package by running the following command: ```bash cd apps/storefront -npm install --save-dev @vue-storefront/next +npm install --save @vue-storefront/next ``` -It is a dedicated Next.js package for Alokai SDK. It simplifies the use of the SDK across the React Server Components and Client Components. +It is a dedicated Next.js package for Alokai Context. It simplifies the use of the SDK and the state across the React Server Components and Client Components. -And that's it! You have successfully installed the Alokai SDK. Now let's configure it to work with SAP Commerce Cloud and Alokai Middleware. +And that's it! You have successfully installed the Alokai Context. Now let's configure it to work with SAP Commerce Cloud and Alokai Middleware. -## Configure Alokai SDK +## Configure Alokai Context -Now that you have successfully installed the Alokai SDK and SAP Commerce Cloud integration, you need to configure the SDK. +Now that you have successfully installed the Alokai Context and SAP Commerce Cloud integration, you need to configure the SDK. -Create a new directory in the `apps/storefront` directory called `sdk`. Inside the `sdk` directory, create a new file called `sdk.config.ts` and add the following code: +Create a new directory in the `apps/storefront` directory called `sdk`. Inside the `sdk` directory, create a new file called `config.ts` and add the following code: ```typescript import { Endpoints } from "@vsf-enterprise/sapcc-api"; -import { CreateSdkOptions, createSdk } from "@vue-storefront/next"; - -const options: CreateSdkOptions = { - middleware: { - apiUrl: "http://localhost:8181", - }, -}; +import { defineSdkConfig } from '@vue-storefront/next'; -export const { getSdk } = createSdk( - options, - ({ buildModule, config, middlewareModule, getRequestHeaders }) => ({ +export function getSdkConfig() { + return defineSdkConfig(({ buildModule, config, getRequestHeaders, middlewareModule }) => ({ sapcc: buildModule(middlewareModule, { - apiUrl: config.middlewareUrl + "/sapcc", + apiUrl: `${config.middlewareUrl}/sapcc`, defaultRequestConfig: { headers: getRequestHeaders(), }, }), }) ); - -export type Sdk = ReturnType; ``` -Next, inside the same folder let's create `sdk.ts` file, where we will create SDK context that will be shared across the application: +Next, inside the same folder let's create `alokai-context.tsx` file, where we will create Alokai context that will be shared across the application: ```typescript "use client"; -import { createSdkContext } from "@vue-storefront/next/client"; +import { createAlokaiContext } from '@vue-storefront/next/client'; +import { User, Cart } from "@vsf-enterprise/sapcc-types"; -import type { Sdk } from "./sdk.config"; +interface SfContract { + SfCart: Cart; + SfCustomer: User; + SfCurrency: string; + SfLocale: string; +} -export const [SdkProvider, useSdk] = createSdkContext(); +import type { Sdk } from './sdk.server'; + +export const { + AlokaiProvider, + useSdk, + useSfCartState, + useSfCurrenciesState, + useSfCurrencyState, + useSfCustomerState, + useSfLocaleState, + useSfLocalesState, +} = createAlokaiContext(); ``` -This will return an `SdkProvider` provider and `useSdk` hook, that will allow us to use the same SDK instance across client side application. -In order to use our shared SDK instance, we need to wrap our Next.js application in the `SdkProvider` provider component. Create a new file inside the same directory named `provider.tsx` and add the following code inside: +This will return an `AlokaiProvider` provider and `useSdk` hook, that will allow us to use the same SDK instance across client side application. +It also will return a set of hooks that will allow us to access the state of the application. +In order to use our shared SDK and state instances, we need to wrap our Next.js application in the `AlokaiProvider` provider component. Along with initializing the `AlokaiProvider` you can pass initial data related to currencies and locales. Create a new file inside the same directory named `provider.tsx` and add the following code inside: ```typescript "use client"; import { ReactNode } from "react"; -import { SdkProvider } from "./sdk"; +import { AlokaiProvider } from "./sdk"; import { getSdk } from "./sdk.config"; export function Providers({ children }: { children: ReactNode }) { - return {children}; + return ( + + {children} + + ); } ``` Now, wrap your application with `` in `apps/storefront/app/layout.tsx`: @@ -108,7 +131,7 @@ export default function RootLayout({ Don't be alarmed if you see a `"use client"` directive in the `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](https://react.dev/reference/react/use-client). -Great job! Alokai Connect is succesfully configured and we can start building! +Great job! Alokai Connect is successfully configured and we can start building! ::info You can find complete implementation in the [`install-sdk` branch](https://github.com/vuestorefront-community/nextjs-starter/tree/install-sdk) @@ -116,7 +139,7 @@ You can find complete implementation in the [`install-sdk` branch](https://githu ## Summary -In this section, we have installed and configured Alokai SDK. We have created an SDK provider and used it in our app layout. +In this section, we have installed and configured Alokai Context. We have created an SDK and state providers and used it in our app layout. In the next section, we will learn how to use Alokai Connect to get the first data from SAP Commerce Cloud and how to use Alokai SDK both in React Server Components and Client Components. @@ -129,4 +152,4 @@ Learn how to get your first data from the SAP Commerce Cloud using Alokai Connec :::docs-button{to="/guides/alokai-essentials/alokai-next-js/first-request"} Next ::: -:: \ No newline at end of file +::