Skip to content

Commit

Permalink
2024-11 update of Alokai Next.js Guide (#7313)
Browse files Browse the repository at this point in the history
* Update react guide (without UDL)

* update react guide udl chapter

* update package versions in react guide

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/5.first-request.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/6.product-page.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/6.product-page.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/4.install-sdk.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/4.install-sdk.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/6.product-page.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add-to-cart.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/9.udl.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/9.udl.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/9.udl.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/9.udl.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/9.udl.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add-to-cart.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add-to-cart.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add-to-cart.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add-to-cart.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add-to-cart.md

Co-authored-by: Matt Maribojoc <[email protected]>

* Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add-to-cart.md

Co-authored-by: Matt Maribojoc <[email protected]>

* docs: add explataion for transformImageUrl function

---------

Co-authored-by: Matt Maribojoc <[email protected]>
  • Loading branch information
mateuszo and mattmaribojoc authored Nov 15, 2024
1 parent 86c3ad5 commit 42f119b
Show file tree
Hide file tree
Showing 10 changed files with 430 additions and 553 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ Before you start, you will need to have the following installed on your machine:
The guide was created and tested using the following versions our our packages:
```json
{
"@vsf-enterprise/sapcc-api": "^7.0.0",
"@vsf-enterprise/unified-api-sapcc": "^2.0.0",
"@vue-storefront/middleware": "^4.3.0",
"@storefront-ui/react": "^2.6.3",
"@vsf-enterprise/sap-commerce-webservices-sdk": "^5.0.1",
"@vue-storefront/next": "^3.0.1",
"@vsf-enterprise/sapcc-api": "^9.0.1",
"@vsf-enterprise/sapcc-types": "^3.0.2",
"@vsf-enterprise/unified-api-sapcc": "^4.0.0",
"@vue-storefront/middleware": "^5.0.1",
"@storefront-ui/react": "^2.6.0",
"@vue-storefront/next": "^4.2.0",
"@vsf-enterprise/sap-commerce-webservices-sdk": "^4.0.0"
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,33 +125,29 @@ touch src/index.ts
Add the following code to the `index.ts` file:

```typescript
import { createServer } from '@vue-storefront/middleware';
import { integrations } from '../middleware.config';
const consola = require('consola');
const cors = require('cors');

(async () => {
const app = await createServer({ integrations });
// By default it's running on the localhost.
const host = process.argv[2] ?? 'localhost';
// By default it's running on the port 8181.
const port = process.argv[3] ?? 8181;
const CORS_MIDDLEWARE_NAME = 'corsMiddleware';

const corsMiddleware = app._router.stack.find(
(middleware: { name: string }) => middleware.name === CORS_MIDDLEWARE_NAME
import { createServer } from "@vue-storefront/middleware";
import { integrations } from "../middleware.config";

const port = Number(process.env.API_PORT) || 8181;

runApp();

async function runApp() {
const app = await createServer(
{ integrations },
{
cors: {
origin: true,
credentials: true,
},
}
);

// You can overwrite the cors settings by defining allowed origins.
corsMiddleware.handle = cors({
origin: ['http://localhost:3000'],
credentials: true
app.listen(port, "", () => {
console.log(`API server listening on port ${port}`);
});
}

app.listen(port, host, () => {
consola.success(`API server listening on http://${host}:${port}`);
});
})();
```

This code will create a new server instance and start the `middleware` application. It will also configure the CORS settings to allow requests from `http://localhost:3000`.
Expand Down Expand Up @@ -185,7 +181,7 @@ npm run dev
To test if the `middleware` application is running correctly, open your terminal and run the following command:

```bash
curl http://localhost:8181/sapcc/searchProduct
curl http://localhost:8181/sapcc/getProducts
```

This will send a request to the `middleware` application and return a response from SAP Commerce Cloud.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,104 +32,34 @@ And that's it! You have successfully installed the Alokai Context. Now let's con

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 `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 `sdk.ts` and add the following code:

```typescript
import { Endpoints } from "@vsf-enterprise/sapcc-api";
import { defineSdkConfig } from '@vue-storefront/next';
import { CreateSdkOptions, createSdk } from "@vue-storefront/next";

export function getSdkConfig() {
return defineSdkConfig(({ buildModule, config, getRequestHeaders, middlewareModule }) => ({
const options: CreateSdkOptions = {
middleware: {
apiUrl: "http://localhost:8181",
},
};

export const { getSdk } = createSdk(
options,
({ buildModule, config, middlewareModule, getRequestHeaders }) => ({
sapcc: buildModule(middlewareModule<Endpoints>, {
apiUrl: `${config.middlewareUrl}/sapcc`,
apiUrl: config.middlewareUrl + "/sapcc",
defaultRequestConfig: {
headers: getRequestHeaders(),
},
}),
})
);
```
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 { createAlokaiContext } from '@vue-storefront/next/client';
import { User, Cart } from "@vsf-enterprise/sapcc-types";

interface SfContract {
SfCart: Cart;
SfCustomer: User;
SfCurrency: string;
SfLocale: string;
}

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

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

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 { AlokaiProvider } from "./sdk";
import { getSdk } from "./sdk.config";

export function Providers({ children }: { children: ReactNode }) {
return (
<AlokaiProvider
initialData={{
currencies: ['USD', 'EUR'],
currency: ['USD'],
locale: 'en',
locales: ['en', 'de'],
}}
sdk={getSdk()}
>
{children}
</AlokaiProvider>
);
}
```
Now, wrap your application with `<Providers>` in `apps/storefront/app/layout.tsx`:
```typescript
import { Providers } from "../sdk/provider";
// imports and metadata object stays the same

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}): JSX.Element {
return (
<html lang="en">
<body className={inter.className}>
<Providers>
{children}
</Providers>
</body>
</html>
);
}
```

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).
In this file we tell the SDK where the middleware resides and what Endpoints are exposed by it. This is the part that ensures
type-safety across the application.

Great job! Alokai Connect is successfully configured and we can start building!

Expand All @@ -139,7 +69,7 @@ You can find complete implementation in the [`install-sdk` branch](https://githu

## Summary

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 this section, we have installed and configured Alokai Connect.

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.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,36 @@ Having a high-level overview of the data flow, we can now proceed to the next se
To create your first request, let's use the existing `storefront/app/page.tsx` file. We will use `searchProduct` SDK method to get the list of products from the SAP Commerce Cloud. For this example, we will utilize Next.js React Server Components to fetch the data on the server side.

```tsx
import { getSdk } from "../sdk/sdk.config"
import { getSdk } from "@/sdk/sdk";

const sdk = getSdk();

export default async function Page() {
const { products } = await sdk.sapcc.searchProduct({});

console.log(products?.map((product) => product.name));

return <div>Page</div>
const {
data: { products },
} = await sdk.sapcc.getProducts({});

return (
<div>
Product List:
<ul>
{products?.map((product) => <li key={product.code}>{product.name}</li>)}
</ul>
</div>
);
}

```

In the code above, we are using Alokai SDK `serachProduct` method to send a request to Alokai Middleware on `/searchProduct` endpoint. Middleware then sends a necessary request to SAP Commerce Cloud and returns response back to Storefront.
In the code above, we are using Alokai SDK's `getProducts` method to send a request to the Alokai Middleware `/getProducts` endpoint. The Middleware then sends a necessary request to SAP Commerce Cloud and returns response back to Storefront.

To run the application, execute the following command:
To run the application, execute the following command (remember that the middleware has to be running as well):

```bash
npm run dev
```

Navigate to `http://localhost:3000` in your browser. You should see the list of product names in the console.
Navigate to `http://localhost:3000` in your browser. You should see a list of products.

![First Request](./images/alokai-app-3.webp)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,23 +75,29 @@ In the `app/globals.css` file, add the following code:
Now, let's use the first Storefront UI component in the `app/page.tsx` file. Add the following code to the file:

```diff
import { getSdk } from "../sdk/sdk.config"
+ import { SfButton } from "@storefront-ui/react"
import { getSdk } from "@/sdk/sdk";
+ import { SfButton } from "@storefront-ui/react";

const sdk = getSdk();

export default async function Page() {
const { products } = await sdk.sapcc.searchProduct({});
const {
data: { products },
} = await sdk.sapcc.getProducts({});

console.log(products?.map((product) => product.name));

- return <div>Page</div>
+ return (
+ <div>
+ <SfButton>Click me</SfButton>
+ </div>
+ )
return (
<div>
+ <div>
+ <SfButton>Click me</SfButton>
+ </div>
Product List:
<ul>
{products?.map((product) => <li key={product.code}>{product.name}</li>)}
</ul>
</div>
);
}

```

This will import the `SfButton` component from Storefront UI. Here's how the result should look like:
Expand Down Expand Up @@ -120,7 +126,7 @@ Let's start building the page!

### Product Details Page

Storefront UI is not like most traditional UI libraries. Blocks are too complex to be used directly imported from the library. It would be very difficult and time consuming to customise them. So, instead, Storefront UI team created Blocks to be copied and pasted into the project and then customised. Since all of the source code is available directly to you, including any styles - you have full control to change the styling.
Storefront UI is not like most traditional UI libraries. Blocks are too complex to be used directly imported from the library. It would be very difficult and time consuming to customize them. So, instead, Storefront UI provides Blocks that can be copied and pasted into the project and then customized. Since all of the source code is available directly to you, including any styles - you have full control to change the styling.

First, let's create new files for the Product Details page. In the `storefront` directory, create a new directory called `components` and inside it create a new file called `ProductDetails.tsx`. Add the code from the [Product Details](https://docs.storefrontui.io/v2/react/blocks/ProductCard.html#details) `Code` tab to the file:

Expand Down Expand Up @@ -275,15 +281,16 @@ Next, repeat the same process for the [Product Gallery with Vertical Thumbnails]

In order to keep the guide short, we will not include the code for all the blocks here. You can find the code in the documentation and in the [nextjs-starter/product-page branch](https://github.com/vuestorefront-community/nextjs-starter/tree/product-page).

Now, let's finally use the Storefront UI Blocks to build a page. For this guide, we will not create a proper dynamic routing for the Product Details page. Instead, we will use the `app/page.tsx` file to build the page.
Now, let's finally use the Storefront UI Blocks to build a page.

Replace the content of the `app/page.tsx` file with the following code:
Create `app/product/[id]/page.tsx` file with the following code:

```tsx
"use client"
import ProductGallery from "../components/ProductGallery";
import ProductDetails from "../components/ProductDetails";
import ProductSlider from "../components/ProductSlider";
"use client";

import ProductDetails from "@/components/ProductDetails";
import ProductGallery from "@/components/ProductGallery";
import ProductSlider from "@/components/ProductSlider";

export default function Page() {
return (
Expand All @@ -292,25 +299,22 @@ export default function Page() {
<ProductDetails />
<ProductSlider />
</div>
)
);
}
```

This will import the Product Details, Product Gallery and Product Slider blocks and use them to build the Product Details page.
```

::info
You may have noticed that we are using "use client" directive at the top of the `app/page.tsx` file. This is done to simplify the guide. In a real application, you would need to add "use client" directive on top of the SFUI Blocks files, since they are using a lot of client side interactions.

We will remove the "use client" directive in the next section when we connect the Product Details page with the SAP Commerce Cloud.
You may have noticed that we are using the `"use client"` directive at the top of the file. This is done to simplify the guide. In a real application, you would need to add `"use client"` directive on each SFUI Blocks files, since they are using a lot of client side interactions.
::

Here's how the result should look like:
Open http://localhost:3000/product/123 Here's how the result should look like:

![Product Details Page](./images/sfui-2.webp)

It's ugly, right? That's because we haven't added any styles to the page. Since Storefront UI uses Tailwind CSS under the hood, we will be using it to add styles to the page. You can find the [Tailwind CSS documentation here](https://tailwindcss.com/docs).

Let's add some styles to the page! In the `app/page.tsx` file, add the following code:
Let's add some styles to the page! In the `app/product/[id]/page.tsx` file, add the following code:

```ts
//... imports
Expand Down Expand Up @@ -342,6 +346,11 @@ This looks much better!

Our Product Details page is ready! With only a few simple steps and a bit of styling, we have built a modern and responsive Product Details page. In the next section, we will learn how to connect the Product Details page with the SAP Commerce Cloud.

::info
You can find the complete implementation in the [`product-page` branch](https://github.com/vuestorefront-community/nextjs-starter/tree/product-page)
::


## Summary

In this guide, we have successfully installed and configured Storefront UI and built a Product Details page using Storefront UI components and blocks. We have also added some basic styles to the page to make it look more appealing and responsive.
Expand Down
Loading

0 comments on commit 42f119b

Please sign in to comment.