Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2024-11 update of Alokai Next.js Guide #7313

Merged
merged 22 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0f28b88
Update react guide (without UDL)
mateuszo Nov 8, 2024
3a3c663
update react guide udl chapter
mateuszo Nov 12, 2024
15c3746
update package versions in react guide
mateuszo Nov 12, 2024
984ca54
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/5.fir…
mateuszo Nov 14, 2024
ee49ea9
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/6.pro…
mateuszo Nov 14, 2024
7afcbb3
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/6.pro…
mateuszo Nov 14, 2024
578e56f
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/4.ins…
mateuszo Nov 14, 2024
d5f3e50
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/4.ins…
mateuszo Nov 14, 2024
4b6a639
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/6.pro…
mateuszo Nov 14, 2024
338ae69
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add…
mateuszo Nov 14, 2024
efd462d
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/9.udl.md
mateuszo Nov 14, 2024
3bb2a01
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/9.udl.md
mateuszo Nov 14, 2024
f9ea180
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/9.udl.md
mateuszo Nov 14, 2024
4028a8f
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/9.udl.md
mateuszo Nov 14, 2024
cc30f44
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/9.udl.md
mateuszo Nov 14, 2024
0c61162
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add…
mateuszo Nov 14, 2024
9058b17
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add…
mateuszo Nov 14, 2024
1c87fe3
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add…
mateuszo Nov 14, 2024
fa06584
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add…
mateuszo Nov 14, 2024
90a5fc3
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add…
mateuszo Nov 14, 2024
ad20425
Update docs/content/guides/2.alokai-essentials/1.alokai-next-js/8.add…
mateuszo Nov 14, 2024
1de7167
docs: add explataion for transformImageUrl function
mateuszo Nov 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 SDK where the middleware resides and what Endpoints are exposed by it. This is the part that ensures
mateuszo marked this conversation as resolved.
Show resolved Hide resolved
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 Context.
mateuszo marked this conversation as resolved.
Show resolved Hide resolved

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 `getProducts` method to send a request to Alokai Middleware on `/getProducts` endpoint. Middleware then sends a necessary request to SAP Commerce Cloud and returns response back to Storefront.
mateuszo marked this conversation as resolved.
Show resolved Hide resolved

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 team created Blocks to 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.
mateuszo marked this conversation as resolved.
Show resolved Hide resolved

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 "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 top of the SFUI Blocks files, since they are using a lot of client side interactions.
mateuszo marked this conversation as resolved.
Show resolved Hide resolved
::

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 complete implementation in the [`product-page` branch](https://github.com/vuestorefront-community/nextjs-starter/tree/product-page)
mateuszo marked this conversation as resolved.
Show resolved Hide resolved
::


## 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
Loading