docs: fixes to payload integration guide (#13261)

This commit is contained in:
Shahed Nasser
2025-08-20 18:06:23 +03:00
committed by GitHub
parent 85ab8e6799
commit e022723e8b
4 changed files with 243 additions and 11 deletions
+121 -1
View File
@@ -73724,6 +73724,8 @@ Now that Payload is set up in your storefront, you'll create the following [coll
- `Media`: A collection for media files, allowing you to manage product images and other media.
- `Product`: A collection for products, which will be synced with Medusa's product data.
Once you're done, you'll add the collections to `src/payload.config.ts`.
#### User Collection
To create the `User` collection, create the file `src/collections/Users.ts` with the following content:
@@ -74180,7 +74182,7 @@ Otherwise, the function validates that:
If any of these validations fail, an error message is returned, preventing the update.
### h. Add Hooks to Sync Product Data
#### Add Hooks to Normalize Product Data
Next, you'll add a `beforeChange` hook to the `Products` collection that will normalize incoming `description` data to [rich-text format](https://payloadcms.com/docs/rich-text/overview).
@@ -74216,6 +74218,32 @@ export const Products: CollectionConfig = {
This hook checks if the `description` field is a string and converts it to rich-text format. This ensures that a description coming from Medusa is properly formatted when stored in Payload.
#### Add Collections to Payload's Configurations
Now that you've created the collections, you need to add them to Payload's configurations.
In `src/payload.config.ts`, add the following imports at the top of the file:
```ts title="src/payload.config.ts" badgeLabel="Storefront" badgeColor="blue"
import { Users } from './collections/Users'
import { Products } from './collections/Products'
import { Media } from './collections/Media'
```
Then, add the collections to the `collections` array of the `buildConfig` function:
```ts title="src/payload.config.ts" badgeLabel="Storefront" badgeColor="blue"
export default buildConfig({
// ...
collections: [
Users,
Products,
Media,
],
// ...
})
```
## i. Generate Payload Imports Map
Before running the Payload admin, you need to generate the imports map that Payload uses to resolve the collections and other configurations.
@@ -75941,6 +75969,98 @@ The workflow will have the following steps:
- [useQueryGraphStep](https://docs.medusajs.com/references/helper-steps/useQueryGraphStep/index.html.md): Retrieve the product variant from Medusa
You only need to create the `updatePayloadItemsStep` step.
#### updatePayloadItemsStep
The `updatePayloadItemsStep` will update an item in a Payload collection, such as `Products`.
To create the step, create the file `src/workflows/steps/update-payload-items.ts` with the following content:
```ts title="src/workflows/steps/update-payload-items.ts" badgeLabel="Medusa application" badgeColor="green"
import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk";
import { PayloadItemResult, PayloadUpsertData } from "../../modules/payload/types";
import { PAYLOAD_MODULE } from "../../modules/payload";
type StepInput = {
collection: string;
items: PayloadUpsertData[];
}
export const updatePayloadItemsStep = createStep(
"update-payload-items",
async ({ items, collection }: StepInput, { container }) => {
const payloadModuleService = container.resolve(PAYLOAD_MODULE)
const ids: string[] = items.map(item => item.id);
const prevData = await payloadModuleService.find(collection, {
where: {
id: {
in: ids.join(",")
}
}
})
const updatedItems: PayloadItemResult[] = []
for (const item of items) {
const { id, ...data } = item;
updatedItems.push(
await payloadModuleService.update(
collection,
data,
{
where: {
id: {
equals: id
}
}
}
)
)
}
return new StepResponse({
items: updatedItems.map(item => item.doc)
}, {
prevData,
collection,
})
},
async (data, { container }) => {
if (!data) {
return;
}
const { prevData, collection } = data;
const payloadModuleService = container.resolve(PAYLOAD_MODULE);
await Promise.all(
prevData.docs.map(async ({
id,
...item
}) => {
await payloadModuleService.update(
collection,
item,
{
where: {
id: {
equals: id
}
}
}
)
})
)
}
)
```
In the step function, you retrieve the existing data from Payload to pass it to the compensation function. Then, you update the items in Payload.
In the compensation function, you revert the changes made in the step function if an error occurs.
#### Create Payload Product Variant Workflow
Create the file `src/workflows/create-payload-product-variant.ts` with the following content:
@@ -246,6 +246,8 @@ Now that Payload is set up in your storefront, you'll create the following [coll
- `Media`: A collection for media files, allowing you to manage product images and other media.
- `Product`: A collection for products, which will be synced with Medusa's product data.
Once you're done, you'll add the collections to `src/payload.config.ts`.
#### User Collection
To create the `User` collection, create the file `src/collections/Users.ts` with the following content:
@@ -716,7 +718,7 @@ Otherwise, the function validates that:
If any of these validations fail, an error message is returned, preventing the update.
### h. Add Hooks to Sync Product Data
#### Add Hooks to Normalize Product Data
Next, you'll add a `beforeChange` hook to the `Products` collection that will normalize incoming `description` data to [rich-text format](https://payloadcms.com/docs/rich-text/overview).
@@ -752,6 +754,32 @@ export const Products: CollectionConfig = {
This hook checks if the `description` field is a string and converts it to rich-text format. This ensures that a description coming from Medusa is properly formatted when stored in Payload.
#### Add Collections to Payload's Configurations
Now that you've created the collections, you need to add them to Payload's configurations.
In `src/payload.config.ts`, add the following imports at the top of the file:
```ts title="src/payload.config.ts" badgeLabel="Storefront" badgeColor="blue"
import { Users } from './collections/Users'
import { Products } from './collections/Products'
import { Media } from './collections/Media'
```
Then, add the collections to the `collections` array of the `buildConfig` function:
```ts title="src/payload.config.ts" badgeLabel="Storefront" badgeColor="blue"
export default buildConfig({
// ...
collections: [
Users,
Products,
Media,
],
// ...
})
```
## i. Generate Payload Imports Map
Before running the Payload admin, you need to generate the imports map that Payload uses to resolve the collections and other configurations.
@@ -2590,6 +2618,98 @@ The workflow will have the following steps:
}}
/>
You only need to create the `updatePayloadItemsStep` step.
#### updatePayloadItemsStep
The `updatePayloadItemsStep` will update an item in a Payload collection, such as `Products`.
To create the step, create the file `src/workflows/steps/update-payload-items.ts` with the following content:
```ts title="src/workflows/steps/update-payload-items.ts" badgeLabel="Medusa application" badgeColor="green"
import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk";
import { PayloadItemResult, PayloadUpsertData } from "../../modules/payload/types";
import { PAYLOAD_MODULE } from "../../modules/payload";
type StepInput = {
collection: string;
items: PayloadUpsertData[];
}
export const updatePayloadItemsStep = createStep(
"update-payload-items",
async ({ items, collection }: StepInput, { container }) => {
const payloadModuleService = container.resolve(PAYLOAD_MODULE)
const ids: string[] = items.map(item => item.id);
const prevData = await payloadModuleService.find(collection, {
where: {
id: {
in: ids.join(",")
}
}
})
const updatedItems: PayloadItemResult[] = []
for (const item of items) {
const { id, ...data } = item;
updatedItems.push(
await payloadModuleService.update(
collection,
data,
{
where: {
id: {
equals: id
}
}
}
)
)
}
return new StepResponse({
items: updatedItems.map(item => item.doc)
}, {
prevData,
collection,
})
},
async (data, { container }) => {
if (!data) {
return;
}
const { prevData, collection } = data;
const payloadModuleService = container.resolve(PAYLOAD_MODULE);
await Promise.all(
prevData.docs.map(async ({
id,
...item
}) => {
await payloadModuleService.update(
collection,
item,
{
where: {
id: {
equals: id
}
}
}
)
})
)
}
)
```
In the step function, you retrieve the existing data from Payload to pass it to the compensation function. Then, you update the items in Payload.
In the compensation function, you revert the changes made in the step function if an error occurs.
#### Create Payload Product Variant Workflow
Create the file `src/workflows/create-payload-product-variant.ts` with the following content:
+1 -1
View File
@@ -6566,6 +6566,6 @@ export const generatedEditDates = {
"app/commerce-modules/order/order-totals/page.mdx": "2025-07-31T15:12:10.633Z",
"app/commerce-modules/user/invite-user-subscriber/page.mdx": "2025-08-01T12:01:54.551Z",
"app/how-to-tutorials/tutorials/invoice-generator/page.mdx": "2025-08-04T00:00:00.000Z",
"app/integrations/guides/payload/page.mdx": "2025-08-15T07:23:50.499Z",
"app/integrations/guides/payload/page.mdx": "2025-08-20T14:48:19.359Z",
"references/js_sdk/admin/Client/methods/js_sdk.admin.Client.getToken/page.mdx": "2025-08-14T12:59:55.678Z"
}
@@ -11517,14 +11517,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
"path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/product-reviews",
"children": []
},
{
"loaded": true,
"isPathHref": true,
"type": "ref",
"title": "Integrate Payload",
"path": "https://docs.medusajs.com/resources/integrations/guides/payload",
"children": []
},
{
"loaded": true,
"isPathHref": true,