Skip to content

Commit

Permalink
docs: add info about state management
Browse files Browse the repository at this point in the history
  • Loading branch information
dawid-ziobro committed Aug 8, 2024
1 parent 6eed9c6 commit 5b42e7e
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 16 deletions.
178 changes: 163 additions & 15 deletions docs/content/4.sdk/2.getting-started/1.index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ 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 provides 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"}

Expand Down Expand Up @@ -67,7 +69,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";
Expand Down Expand Up @@ -159,21 +161,57 @@ import { getSdk } from "@/sdk/sdk.server";
const sdk = getSdk();
```

### createSdkContext
### createAlokaiContext

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`:
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-provider.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<Sdk>();
export const {AlokaiProvider, useSdk} = createAlokaiContext<Sdk>();
```

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`:
Now let's extend the config file with the state management part:

```ts
'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<Sdk>(); // [!code --]
// [!code ++:11]
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
- customer
- currency
- locale

Once you have created the SDK context, you can create client-side SDK instance and register it in your application.
You can pass initial data related to currencies and locales to the `AlokaiProvider` provider component.
For example, if you're using the Pages Router, you can register it in `pages/_app.tsx`:

```tsx
import type { AppProps } from "next/app";
Expand All @@ -188,9 +226,17 @@ export default function App({ Component, pageProps }: AppProps) {
);

return (
<SdkProvider sdk={getSdk()}>
<AlokaiProvider
initialData={{
currencies: ['USD', 'EUR'],
currency: 'USD',
locale: 'en',
locales: ['en', 'de'],
}}
sdk={getSdk()}
>
<Component {...pageProps} />
</SdkProvider>
</AlokaiProvider>
);
}
```
Expand Down Expand Up @@ -232,8 +278,19 @@ export function Providers({ children, sdkOptions }: { children: ReactNode, sdkOp
sdkOptions,
getSdkConfig()
);

return <SdkProvider sdk={getSdk()}>{children}</SdkProvider>;
return (
<AlokaiProvider
initialData={{
currencies: ['USD', 'EUR'],
currency: 'USD',
locale: 'en',
locales: ['en', 'de'],
}}
sdk={getSdk()}
>
{children}
</AlokaiProvider>
)
}
```

Expand All @@ -250,7 +307,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();

Expand Down Expand Up @@ -296,6 +353,58 @@ export function ClientComponentUsingSDK() {

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).

### State management

Along with the SDK, the package `@vue-storefront/next` brings a state management solution. It is automatically configured and ready to use.
The state manager allows you to manage the global state of your application for core entities like:
- cart
- customer
- currency
- locale

The state management is based on the [Zustand](https://github.com/pmndrs/zustand) library. It provides a set of hooks to manage the state of your application.

Example usage of state management:

```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 (
<div>
<p>Cart total: {cart.total}</p>
<p>
Customer name: {customer.firstName} {customer.lastName}
</p>
<p>Currency: {currency}</p>
<p>Locale: {locale}</p>
</div>
);
}
```

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

#tab-2
Expand Down Expand Up @@ -373,7 +482,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`)
Expand All @@ -396,7 +505,7 @@ const { data: products } = await useAsyncData("products", () =>
</script>
```

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 ✨

Expand Down Expand Up @@ -513,7 +622,46 @@ 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).

### State management

Along with the SDK, the package `@vue-storefront/nuxt` brings a state management solution. It is automatically configured and ready to use.
The state manager allows you to manage the global state of your application for core entities like:
- cart
- customer
- currency
- locale

The solution is based on [Pinia](https://pinia.vuejs.org/) and it utilises it's api.
To use it, 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.

Example usage of state management:

```vue
<template>
<div>
<p>Cart total: {{ cart.total }}</p>
<p>Customer name: {{ customer.firstName }} {{ customer.lastName }}</p>
<p>Currency: {{ currency }}</p>
<p>Locale: {{ locale }}</p>
</div>
</template>
<script setup>
const { cart, customer, currency, currencies, locale, locales } = storeToRefs(
useSfState()
);
// updating the currency state
currency.value = "USD";
// updating the cart state
onMounted(async () => {
cart.value = await useSdk().unified.getCart();
});
</script>
```

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<UnifiedEndpoints>, {
apiUrl: config.middlewareUrl + "/commerce", // SAP Commerce Cloud integration is available at /commerce endpoint
defaultRequestConfig: {
Expand Down

0 comments on commit 5b42e7e

Please sign in to comment.