diff --git a/www/apps/resources/app/how-to-tutorials/tutorials/first-purchase-discounts/page.mdx b/www/apps/resources/app/how-to-tutorials/tutorials/first-purchase-discounts/page.mdx
index 9cfcd6367d..7e91f28060 100644
--- a/www/apps/resources/app/how-to-tutorials/tutorials/first-purchase-discounts/page.mdx
+++ b/www/apps/resources/app/how-to-tutorials/tutorials/first-purchase-discounts/page.mdx
@@ -27,7 +27,7 @@ export const metadata = {
In this tutorial, you'll learn how to implement first-purchase discounts in Medusa.
-When you install a Medusa application, you get a fully-fledged commerce platform with a Framework for customization. The Medusa application's commerce features are built around [Commerce Modules](../../../commerce-modules/page.mdx), which are available out-of-the-box. These features include promotion and discount management features.
+When you install a Medusa application, you get a fully-fledged commerce platform with a Framework for customization. The Medusa application's commerce features are built around [Commerce Modules](../../../commerce-modules/page.mdx), which are available out-of-the-box. These features include promotion and cart management features.
The first-purchase discount feature encourages customers to sign up and make their first purchase by offering them a discount. In this tutorial, you'll learn how to implement this feature in Medusa.
@@ -227,8 +227,8 @@ export const applyFirstPurchasePromoWorkflow = createWorkflow(
entity: "cart",
fields: ["promotions.*", "customer.*", "customer.orders.*"],
filters: {
- id: input.cart_id
- }
+ id: input.cart_id,
+ },
})
const { data: promotions } = useQueryGraphStep({
@@ -241,7 +241,7 @@ export const applyFirstPurchasePromoWorkflow = createWorkflow(
when({
carts,
- promotions
+ promotions,
}, (data) => {
return data.promotions.length > 0 &&
!data.carts[0].promotions?.some((promo) => promo?.id === data.promotions[0].id) &&
@@ -252,7 +252,7 @@ export const applyFirstPurchasePromoWorkflow = createWorkflow(
updateCartPromotionsStep({
id: carts[0].id,
promo_codes: [promotions[0].code!],
- action: PromotionActions.ADD
+ action: PromotionActions.ADD,
})
})
@@ -261,8 +261,8 @@ export const applyFirstPurchasePromoWorkflow = createWorkflow(
entity: "cart",
fields: ["*", "promotions.*"],
filters: {
- id: input.cart_id
- }
+ id: input.cart_id,
+ },
}).config({ name: "retrieve-updated-cart" })
return new WorkflowResponse(updatedCarts[0])
@@ -319,8 +319,8 @@ export default async function cartCreatedHandler({
await applyFirstPurchasePromoWorkflow(container)
.run({
input: {
- cart_id: data.id
- }
+ cart_id: data.id,
+ },
})
}
@@ -429,8 +429,8 @@ updateCartPromotionsWorkflow.hooks.validate(
entity: "customer",
fields: ["orders.*", "has_account"],
filters: {
- id: cart.customer_id
- }
+ id: cart.customer_id,
+ },
})
if (!customer.has_account || (customer?.orders?.length || 0) > 0) {
@@ -474,7 +474,7 @@ In the same `src/workflows/hooks/validate-promotion.ts` file, add the following
```ts title="src/workflows/hooks/validate-promotion.ts"
import {
- completeCartWorkflow
+ completeCartWorkflow,
} from "@medusajs/medusa/core-flows"
```
@@ -511,8 +511,8 @@ completeCartWorkflow.hooks.validate(
entity: "customer",
fields: ["orders.*", "has_account"],
filters: {
- id: cart.customer_id
- }
+ id: cart.customer_id,
+ },
})
if (!customer.has_account || (customer?.orders?.length || 0) > 0) {
diff --git a/www/apps/resources/app/how-to-tutorials/tutorials/gift-message/page.mdx b/www/apps/resources/app/how-to-tutorials/tutorials/gift-message/page.mdx
new file mode 100644
index 0000000000..fe69165412
--- /dev/null
+++ b/www/apps/resources/app/how-to-tutorials/tutorials/gift-message/page.mdx
@@ -0,0 +1,688 @@
+---
+sidebar_label: "Add Gift Message"
+tags:
+ - cart
+ - order
+ - server
+ - nextjs
+ - tutorial
+products:
+ - cart
+ - order
+---
+
+import { Github } from "@medusajs/icons"
+import { Prerequisites, WorkflowDiagram, CardList } from "docs-ui"
+
+export const metadata = {
+ title: `Add Gift Message to Line Items in Medusa`,
+}
+
+# {metadata.title}
+
+In this tutorial, you will learn how to add a gift message to items in carts and orders in Medusa.
+
+When you install a Medusa application, you get a fully-fledged commerce platform with a Framework for customization. The Medusa application's commerce features are built around [Commerce Modules](../../../commerce-modules/page.mdx), which are available out-of-the-box. These features include cart and order management capabilities.
+
+You can customize the Medusa application and storefront to add a gift message to items in the cart. This feature allows customers to add a personalized message to their gifts, enhancing the shopping experience.
+
+## Summary
+
+By following this tutorial, you will learn how to:
+
+- Install and set up Medusa and the Next.js Starter Storefront.
+- Customize the storefront to support gift messages on cart items during checkout.
+- Customize the Medusa Admin to show gift items with messages in an order.
+
+You can follow this tutorial whether you're new to Medusa or an advanced Medusa developer.
+
+
+
+---
+
+## Step 1: Install a Medusa Application
+
+
+
+Start by installing the Medusa application on your machine with the following command:
+
+```bash
+npx create-medusa-app@latest
+```
+
+First, you'll be asked for the project's name. Then, when prompted about installing the [Next.js Starter Storefront](../../../nextjs-starter/page.mdx), choose "Yes."
+
+Afterward, the installation process will start, which will install the Medusa application in a directory with your project's name and the Next.js Starter Storefront in a separate directory named `{project-name}-storefront`.
+
+
+
+The Medusa application is composed of a headless Node.js server and an admin dashboard. The storefront is installed or custom-built separately and connects to the Medusa application through its REST endpoints, called [API routes](!docs!/learn/fundamentals/api-routes). Learn more in [Medusa's Architecture documentation](!docs!/learn/introduction/architecture).
+
+
+
+Once the installation finishes successfully, the Medusa Admin dashboard will open with a form to create a new user. Enter the user's credentials and submit the form. Afterward, you can log in with the new user and explore the dashboard.
+
+
+
+Check out the [troubleshooting guides](../../../troubleshooting/create-medusa-app-errors/page.mdx) for help.
+
+
+
+---
+
+## Step 2: Add Gift Inputs to Cart Item
+
+In this step, you'll customize the Next.js Starter Storefront to allow customers to specify that an item is a gift and add a gift message to it.
+
+You'll store the gift option and message in the cart item's `metadata` property, which is a key-value `jsonb` object that can hold any additional information about the item. When the customer places the order, the `metadata` is copied to the `metadata` of the order's line items.
+
+So, you only need to customize the storefront to add the gift message input and update the cart item metadata.
+
+### a. Changes to Update Item Function
+
+The Next.js Starter Storefront has an `updateLineItem` function that sends a request to the Medusa server to update the cart item. However, it doesn't support updating the `metadata` property.
+
+So, in `src/lib/data/cart.ts`, find the `updateLineItem` function and add a `metadata` property to its object parameter:
+
+```ts title="src/lib/data/cart.ts" badgeLabel="Storefront" badgeColor="blue" highlights={[["4"], ["8"]]}
+export async function updateLineItem({
+ lineId,
+ quantity,
+ metadata,
+}: {
+ lineId: string
+ quantity: number
+ metadata?: Record
+}) {
+ // ...
+}
+```
+
+Next, change the usage of `await sdk.store.cart.updateLineItem` in the function to pass the `metadata` property:
+
+```ts title="src/lib/data/cart.ts" badgeLabel="Storefront" badgeColor="blue"
+const updateData: any = { quantity }
+if (metadata) {
+ updateData.metadata = metadata
+}
+
+await sdk.store.cart
+ .updateLineItem(cartId, lineId, updateData, {}, headers)
+// ...
+```
+
+You pass the `metadata` property to the Medusa server, which will update the cart item with the new metadata.
+
+### b. Add Gift Inputs
+
+Next, you'll modify the cart item component that's shown in the cart and checkout pages to show two inputs: one to specify that the item is a gift and another to add a gift message.
+
+In `src/modules/cart/components/item/index.tsx`, add the following imports at the top of the file:
+
+```tsx title="src/modules/cart/components/item/index.tsx" badgeLabel="Storefront" badgeColor="blue"
+import { Checkbox, Textarea, Button, Label } from "@medusajs/ui"
+```
+
+You import components from the [Medusa UI library](!ui!) that will be useful for the gift inputs.
+
+Next, in the `Item` component, add the following variables before the `changeQuantity` function:
+
+export const giftVarsHighlights = [
+ ["1", "giftUpdating", "Track whether the gift message is being updated"],
+ ["2", "newGiftMessage", "Hold the new gift message input value."],
+ ["5", "isEditingGiftMessage", "Track whether the gift message input is being edited."],
+ ["7", "isGift", "Indicate whether the item is a gift."],
+ ["8", "giftMessage", "Current gift message from item's metadata."]
+]
+
+```tsx title="src/modules/cart/components/item/index.tsx" badgeLabel="Storefront" badgeColor="blue" highlights={giftVarsHighlights}
+const [giftUpdating, setGiftUpdating] = useState(false)
+const [newGiftMessage, setNewGiftMessage] = useState(
+ item.metadata?.gift_message as string || ""
+)
+const [isEditingGiftMessage, setIsEditingGiftMessage] = useState(false)
+
+const isGift = item.metadata?.is_gift === "true"
+const giftMessage = item.metadata?.gift_message as string
+```
+
+You define the following variables:
+
+- `giftUpdating`: A state variable to track whether the gift message is being updated. This will be useful to handle loading and disabled states.
+- `newGiftMessage`: A state variable to hold the new gift message input value.
+- `isEditingGiftMessage`: A state variable to track whether the gift message input is being edited. This will be useful to show or hide the input field.
+- `isGift`: A boolean indicating whether the item is a gift based on the `metadata.is_gift` property.
+- `giftMessage`: The current gift message from the item's `metadata.gift_message` property.
+
+Next, add the following functions before the `return` statement to handle updates to the gift inputs:
+
+export const giftFunctionsHighlights = [
+ ["1", "handleGiftToggle", "Handle the gift checkbox toggle."],
+ ["22", "handleSaveGiftMessage", "Handle saving the gift message."],
+ ["44", "handleStartEdit", "Enable editing the gift message input."],
+ ["48", "handleCancelEdit", "Cancel editing the gift message input."]
+]
+
+```tsx title="src/modules/cart/components/item/index.tsx" badgeLabel="Storefront" badgeColor="blue" highlights={giftFunctionsHighlights}
+const handleGiftToggle = async (checked: boolean) => {
+ setGiftUpdating(true)
+
+ try {
+ const newMetadata = {
+ is_gift: checked.toString(),
+ gift_message: checked ? newGiftMessage : "",
+ }
+
+ await updateLineItem({
+ lineId: item.id,
+ quantity: item.quantity,
+ metadata: newMetadata,
+ })
+ } catch (error) {
+ console.error("Error updating gift status:", error)
+ } finally {
+ setGiftUpdating(false)
+ }
+}
+
+const handleSaveGiftMessage = async () => {
+ setGiftUpdating(true)
+
+ try {
+ const newMetadata = {
+ is_gift: "true",
+ gift_message: newGiftMessage,
+ }
+
+ await updateLineItem({
+ lineId: item.id,
+ quantity: item.quantity,
+ metadata: newMetadata,
+ })
+ setIsEditingGiftMessage(false)
+ } catch (error) {
+ console.error("Error updating gift message:", error)
+ } finally {
+ setGiftUpdating(false)
+ }
+}
+
+const handleStartEdit = () => {
+ setIsEditingGiftMessage(true)
+}
+
+const handleCancelEdit = () => {
+ setNewGiftMessage(giftMessage || "")
+ setIsEditingGiftMessage(false)
+}
+```
+
+You define the following functions:
+
+- `handleGiftToggle`: Used when the gift checkbox is toggled. It updates the cart item's metadata to set the `is_gift` and `gift_message` properties based on the checkbox state.
+- `handleSaveGiftMessage`: Used to save the gift message when the customer clicks the "Save" button. It updates the cart item's metadata with the new gift message.
+- `handleStartEdit`: Used to start editing the gift message input by setting the `isEditingGiftMessage` state to `true`.
+- `handleCancelEdit`: Used to cancel the gift message editing and reset the input value to the current gift message.
+
+Finally, you'll change the `return` statement to include the gift inputs. Replace the existing return statement with the following:
+
+```tsx title="src/modules/cart/components/item/index.tsx" badgeLabel="Storefront" badgeColor="blue"
+return (
+
+)
+```
+
+You replace the previous table row design with a card. In the card, you show the item's image, title, variant options, quantity, and price.
+
+You also show a checkbox to toggle the gift status of the item. If the item is a gift, you show a text area to add or edit the gift message. You only show the gift message input if the user clicks an "Add" or "Edit" button.
+
+The gift message input has a "Save" button to save the message and a "Cancel" button to cancel the editing.
+
+### c. Update Cart and Checkout Templates
+
+The items are previously shown on the cart and checkout pages in a table. However, since you've changed the item component to a card, you'll need to update the cart and checkout templates to replace the table with a list of items.
+
+In `src/modules/cart/templates/items.tsx`, which shows the items on the cart page, change the `return` statement to the following:
+
+```tsx title="src/modules/cart/templates/items.tsx" badgeLabel="Storefront" badgeColor="blue"
+return (
+
+)
+```
+
+You replace the table that was wrapping the items with a `div` that contains a list of `Item` components.
+
+Next, in `src/modules/cart/templates/preview.tsx` that shows the items in the checkout summary, change the `return` statement to the following:
+
+```tsx title="src/modules/cart/templates/preview.tsx" badgeLabel="Storefront" badgeColor="blue"
+return (
+
+)
+```
+
+Similarly, you replace the table that was wrapping the items with a `div` that contains a list of `Item` components.
+
+### Test the Changes
+
+You can now test the gift inputs during checkout.
+
+First, start the Medusa application by running the following command in the Medusa application directory:
+
+```bash npm2yarn badgeLabel="Medusa Application" badgeColor="green"
+npm run dev
+```
+
+Then, start the Next.js Starter Storefront by running the following command in the storefront directory:
+
+```bash npm2yarn badgeLabel="Storefront" badgeColor="blue"
+npm run dev
+```
+
+Open the storefront in your browser at `http://localhost:8000`. Add a product to the cart, and proceed to the checkout page. You'll find a checkbox to mark the item as a gift for each item.
+
+
+
+If you check the box, you can also add and edit the gift message. The gift message will be saved in the cart item's `metadata`.
+
+
+
+---
+
+## Step 3: Show Gift Options in Order Confirmation Page
+
+Next, you'll customize the storefront to show the gift message of items in the order confirmation page.
+
+In `src/modules/order/components/item/index.tsx`, add in the `Item` component the following variables:
+
+```tsx title="src/modules/order/components/item/index.tsx" badgeLabel="Storefront" badgeColor="blue"
+const isGift = item.metadata?.is_gift === "true"
+const giftMessage = item.metadata?.gift_message as string
+```
+
+You define the following variables:
+
+- `isGift`: A boolean indicating whether the item is a gift based on the `metadata.is_gift` property.
+- `giftMessage`: The item's gift message from the `metadata.gift_message` property.
+
+Next, in the `return` statement, add the following below the `LineItemOptions` component:
+
+```tsx title="src/modules/order/components/item/index.tsx" badgeLabel="Storefront" badgeColor="blue"
+{isGift &&
+ Gift Message: {giftMessage || "No gift message provided"}
+}
+```
+
+If the item is a gift, you show the gift message below the variant options. If no gift message is provided, you show "No gift message provided."
+
+### Test the Changes
+
+To test this change, place an order with a gift item. On the order confirmation page, you should see the gift message displayed below the variant options.
+
+
+
+---
+
+## Step 4: Show Gift Options in Admin Dashboard
+
+In this step, you'll customize the Medusa Admin dashboard to show the gift items with their messages in an order.
+
+### What is a Widget?
+
+The Medusa Admin dashboard's pages are customizable to insert [widgets](!docs!/learn/fundamentals/admin/widgets) of custom content in predefined injection zones. You create these widgets as React components that allow admin users to perform custom actions.
+
+So, to show the gift items with their messages in an order, you'll create a custom widget that shows the gift items in the order details page.
+
+### Create the Widget
+
+You create a widget in a `.tsx` file under the `src/admin/widgets` directory. So, in the Medusa application directory, create the file `src/admin/widgets/order-gift-items-widget.tsx` with the following content:
+
+```tsx title="src/admin/widgets/order-gift-items-widget.tsx" badgeLabel="Medusa Application" badgeColor="green"
+import { defineWidgetConfig } from "@medusajs/admin-sdk"
+import { Container, Text } from "@medusajs/ui"
+import { DetailWidgetProps, AdminOrder } from "@medusajs/framework/types"
+
+const OrderGiftItemsWidget = ({ data }: DetailWidgetProps) => {
+ const giftItems = data.items?.filter(
+ (item: any) => item.metadata?.is_gift === "true"
+ )
+
+ if (!giftItems?.length) {
+ return null
+ }
+
+ return (
+
+ Gift Items & Messages
+
+
+ )
+}
+
+export const config = defineWidgetConfig({
+ zone: "order.details.side.after",
+})
+
+export default OrderGiftItemsWidget
+```
+
+A widget file must export:
+
+- A React component that renders the widget content.
+- A configuration object created with `defineWidgetConfig` that defines the widget's [injection zone](/admin-widget-injection-zones).
+
+You define the `OrderGiftItemsWidget` component that is injected in the `order.details.side.after` zone. Because it's injected in the order details page, it receives the order details as a `data` prop.
+
+In the component, you filter the order items to get only the gift items by checking if the `metadata.is_gift` property is set to `"true"`. Then, you render the gift items with their messages in a new "Gift Items & Messages" section.
+
+### Test Medusa Admin Changes
+
+To test out the Medusa Admin widget, start the Medusa application by running the following command in the Medusa application directory:
+
+```bash npm2yarn badgeLabel="Medusa Application" badgeColor="green"
+npm run dev
+```
+
+Then, open the Medusa Admin at `http://localhost:9000/app` and log in with the user you created earlier.
+
+Go to the Orders page and click on an order that has gift items. You'll find a new section called "Gift Items & Messages" that shows the gift items with their messages.
+
+
+
+---
+
+## Optional: Handle Gift Items in Fulfillment Provider
+
+If you have a custom fulfillment provider and you want to handle gift items in it, you can do so in the `createFulfillment` method of the [Fulfillment Module Provider's service](/references/fulfillment/provider).
+
+For example:
+
+export const createFulfillmentHighlights = [
+ ["9", "itemsWithGiftMessage", "Filter order items to find gift items."],
+]
+
+```ts title="Fulfillment Module Provider's Service" badgeLabel="Medusa Application" badgeColor="green" highlights={createFulfillmentHighlights}
+class ManualFulfillmentService extends utils_1.AbstractFulfillmentProviderService {
+ // ...
+ async createFulfillment(
+ data: Record,
+ items: Partial>[],
+ order: Partial | undefined,
+ fulfillment: Partial>
+ ): Promise {
+ const itemsWithGiftMessage = order.items?.filter((lineItem) => {
+ const isInFulfillment = items.find(
+ (item) => item.line_item_id === lineItem.id
+ )
+ if (!isInFulfillment) {
+ return false
+ }
+ return lineItem.metadata?.is_gift === "true"
+ })
+
+ // TODO pass gift items to third-party provider
+ }
+}
+```
+
+You filter the order items to find the items that are part of the fulfillment and are gift items. You can then process or pass them differently to your third-party provider.
+
+---
+
+## Next Steps
+
+You've now added gift messages to items in carts and orders in Medusa.
+
+If you're new to Medusa, check out the [main documentation](!docs!/learn), where you'll get a more in-depth understanding of all the concepts you've used in this guide and more.
+
+To learn more about the commerce features that Medusa provides, check out Medusa's [Commerce Modules](../../../commerce-modules/page.mdx).
+
+### Troubleshooting
+
+If you encounter issues during your development, check out the [troubleshooting guides](../../../troubleshooting/page.mdx).
+
+### Getting Help
+
+If you encounter issues not covered in the troubleshooting guides:
+
+1. Visit the [Medusa GitHub repository](https://github.com/medusajs/medusa) to report issues or ask questions.
+2. Join the [Medusa Discord community](https://discord.gg/medusajs) for real-time support from community members.
diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs
index a2bc59ee3d..a31dd54486 100644
--- a/www/apps/resources/generated/edit-dates.mjs
+++ b/www/apps/resources/generated/edit-dates.mjs
@@ -6546,6 +6546,8 @@ export const generatedEditDates = {
"references/utils/utils.Payment/page.mdx": "2025-06-05T19:05:53.489Z",
"app/integrations/guides/slack/page.mdx": "2025-06-26T12:57:20.880Z",
"app/integrations/guides/sentry/page.mdx": "2025-06-16T10:11:29.955Z",
+ "app/integrations/guides/mailchimp/page.mdx": "2025-06-24T08:08:35.034Z",
+ "app/how-to-tutorials/tutorials/first-purchase-discounts/page.mdx": "2025-06-26T09:13:19.296Z",
"app/integrations/guides/mailchimp/page.mdx": "2025-06-26T11:59:15.303Z",
"app/how-to-tutorials/tutorials/first-purchase-discounts/page.mdx": "2025-06-26T11:55:27.175Z",
"references/types/CommonTypes/interfaces/types.CommonTypes.CookieOptions/page.mdx": "2025-06-25T10:11:37.088Z",
@@ -6554,5 +6556,6 @@ export const generatedEditDates = {
"references/workflows/IDistributedTransactionStorage/methods/workflows.IDistributedTransactionStorage.clearExpiredExecutions/page.mdx": "2025-06-25T10:11:44.945Z",
"references/types/interfaces/types.InitiatePaymentOutput/page.mdx": "2025-06-25T10:11:39.942Z",
"references/types/interfaces/types.UpdatePaymentOutput/page.mdx": "2025-06-25T10:11:39.945Z",
+ "app/how-to-tutorials/tutorials/gift-message/page.mdx": "2025-06-26T09:13:19.296Z",
"app/how-to-tutorials/tutorials/re-order/page.mdx": "2025-06-26T12:38:24.308Z"
}
\ No newline at end of file
diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs
index ea734cad91..6606a59579 100644
--- a/www/apps/resources/generated/files-map.mjs
+++ b/www/apps/resources/generated/files-map.mjs
@@ -743,6 +743,10 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/how-to-tutorials/tutorials/first-purchase-discounts/page.mdx",
"pathname": "/how-to-tutorials/tutorials/first-purchase-discounts"
},
+ {
+ "filePath": "/www/apps/resources/app/how-to-tutorials/tutorials/gift-message/page.mdx",
+ "pathname": "/how-to-tutorials/tutorials/gift-message"
+ },
{
"filePath": "/www/apps/resources/app/how-to-tutorials/tutorials/loyalty-points/page.mdx",
"pathname": "/how-to-tutorials/tutorials/loyalty-points"
diff --git a/www/apps/resources/generated/generated-how-to-tutorials-sidebar.mjs b/www/apps/resources/generated/generated-how-to-tutorials-sidebar.mjs
index 71810af941..7403d8d79f 100644
--- a/www/apps/resources/generated/generated-how-to-tutorials-sidebar.mjs
+++ b/www/apps/resources/generated/generated-how-to-tutorials-sidebar.mjs
@@ -366,6 +366,15 @@ const generatedgeneratedHowToTutorialsSidebarSidebar = {
"description": "Learn how to send abandoned cart notifications to customers.",
"children": []
},
+ {
+ "loaded": true,
+ "isPathHref": true,
+ "type": "link",
+ "title": "Add Gift Message",
+ "path": "/how-to-tutorials/tutorials/gift-message",
+ "description": "Learn how to add a gift option and message to items in the cart.",
+ "children": []
+ },
{
"loaded": true,
"isPathHref": true,
diff --git a/www/apps/resources/sidebars/how-to-tutorials.mjs b/www/apps/resources/sidebars/how-to-tutorials.mjs
index 15c7eb8ca7..b2c7e01f28 100644
--- a/www/apps/resources/sidebars/how-to-tutorials.mjs
+++ b/www/apps/resources/sidebars/how-to-tutorials.mjs
@@ -72,6 +72,13 @@ export const howToTutorialsSidebar = [
While tutorials show you a specific use case, they also help you understand how to implement similar use cases in your own projects. Also, you can implement the use case in a tutorial differently to fit your business requirements.`,
children: [
+ {
+ type: "link",
+ title: "Add Gift Message",
+ path: "/how-to-tutorials/tutorials/gift-message",
+ description:
+ "Learn how to add a gift option and message to items in the cart.",
+ },
{
type: "ref",
title: "Analytics with Segment",
diff --git a/www/packages/tags/src/tags/cart.ts b/www/packages/tags/src/tags/cart.ts
index 6b67946a9d..f61a72b020 100644
--- a/www/packages/tags/src/tags/cart.ts
+++ b/www/packages/tags/src/tags/cart.ts
@@ -19,6 +19,10 @@ export const cart = [
"title": "Implement First-Purchase Discount",
"path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/first-purchase-discounts"
},
+ {
+ "title": "Add Gift Message",
+ "path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/gift-message"
+ },
{
"title": "Implement Loyalty Points",
"path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/loyalty-points"
diff --git a/www/packages/tags/src/tags/file.ts b/www/packages/tags/src/tags/file.ts
index d026a432af..7fd6e99e40 100644
--- a/www/packages/tags/src/tags/file.ts
+++ b/www/packages/tags/src/tags/file.ts
@@ -19,10 +19,6 @@ export const file = [
"title": "generateProductCsvStep",
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/steps/generateProductCsvStep"
},
- {
- "title": "normalizeCsvToChunksStep",
- "path": "https://docs.medusajs.com/resources/references/medusa-workflows/steps/normalizeCsvToChunksStep"
- },
{
"title": "processImportChunksStep",
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/steps/processImportChunksStep"
diff --git a/www/packages/tags/src/tags/nextjs.ts b/www/packages/tags/src/tags/nextjs.ts
index 29a862e127..356cf1ffca 100644
--- a/www/packages/tags/src/tags/nextjs.ts
+++ b/www/packages/tags/src/tags/nextjs.ts
@@ -3,6 +3,10 @@ export const nextjs = [
"title": "First-Purchase Discount",
"path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/first-purchase-discounts"
},
+ {
+ "title": "Add Gift Message",
+ "path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/gift-message"
+ },
{
"title": "Saved Payment Methods",
"path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/saved-payment-methods"
diff --git a/www/packages/tags/src/tags/server.ts b/www/packages/tags/src/tags/server.ts
index 10a28a6dbf..2fbea7e783 100644
--- a/www/packages/tags/src/tags/server.ts
+++ b/www/packages/tags/src/tags/server.ts
@@ -51,6 +51,10 @@ export const server = [
"title": "First-Purchase Discount",
"path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/first-purchase-discounts"
},
+ {
+ "title": "Add Gift Message",
+ "path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/gift-message"
+ },
{
"title": "Loyalty Points",
"path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/loyalty-points"
diff --git a/www/packages/tags/src/tags/tutorial.ts b/www/packages/tags/src/tags/tutorial.ts
index 09ff51f0eb..2d5b463524 100644
--- a/www/packages/tags/src/tags/tutorial.ts
+++ b/www/packages/tags/src/tags/tutorial.ts
@@ -31,6 +31,10 @@ export const tutorial = [
"title": "First-Purchase Discount",
"path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/first-purchase-discounts"
},
+ {
+ "title": "Add Gift Message",
+ "path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/gift-message"
+ },
{
"title": "Loyalty Points",
"path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/loyalty-points"