---
addHowToData: true
---

import DocCardList from '@theme/DocCardList';
import Icons from '@theme/Icon';

# Personalized Products

This document guides you through the different documentation resources to help you build personalized products with Medusa.

## Overview

Personalized products are products that customers can customize based on their need. For example, they can upload an image to print on a shirt or provide a message to include in a letter.

Medusa’s customizable architecture allows you to customize its entities or create your own to implement and store personalized products. Also, as the Medusa backend is headless, you have freedom in how you choose to implement the storefront. This is essential for ecommerce stores that provide personalized products, as you typically build a unique experience around your products.

---

## Store Personalized Data

Most of the entities in Medusa’s core include a `metadata` attribute. This attribute helps store custom data in the core entities.

The `Product` entity represents the main product, whereas the `ProductVariant` is the different saleable options of that product. For example, a shirt is a `Product`, and each different color of the shirt is the `ProductVariant`. The `LineItem` entity is the product variant added to the cart.

So, you can use the `metadata` attribute of the `LineItem` entity to store the customer’s personalization. Optionally, you can use the `metadata` attribute in the `Product` or `ProductVariant` to store the expected format of personalized data. This depends on your use case and how basic or complex it is.

For example, if you’re asking customers to enter a message to put in a letter they’re purchasing, you can use the `metadata` attribute of the `LineItem` entity to set the personalized information entered by the customer.

Note that two Line Items in the cart having different `metadata` attributes are not considered the same item. So, each Line Item is managed separately and can have its own quantity.

In more complex cases, you can extend entities from the core, such as the `Product` entity, to add more attributes. You can also create new custom entities to hold your personalized data and logic.

<DocCardList colSize={4} items={[
  {
    type: 'link',
    href: '/development/entities/overview#metadata-attribute',
    label: 'Metadata Attribute',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn about the metadata attribute and how to use it.',
    }
  },
  {
    type: 'link',
    href: '/development/entities/create',
    label: 'Create an Entity',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to create an entity in the Medusa backend.',
    }
  },
  {
    type: 'link',
    href: '/development/entities/extend-entity',
    label: 'Extend an Entity',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to extend an entity in the Medusa backend.',
    }
  },
]} />

---

## Build a Custom Storefront

Medusa provides a headless backend that can be accessed through REST APIs. So, there are no restrictions on what language or framework you use to build the storefront or what design or experience you provide customers.

You can build a unique experience around your products that focuses on the customer’s personalization capabilities.

Medusa provides a Next.js storefront starter with basic ecommerce functionalities that can be used and modified. You can also build your own storefront by using Medusa’s client libraries or REST APIs to communicate with the backend from the storefront.

<DocCardList colSize={6} items={[
  {
    type: 'link',
    href: '/starters/nextjs-medusa-starter',
    label: 'Next.js Starter',
    customProps: {
      icon: Icons['nextjs'],
      description: 'Learn about the Next.js starter and how to install it.',
    }
  },
  {
    type: 'link',
    href: '/storefront/roadmap',
    label: 'Build Your Own Storefront',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Follow this roadmap to learn how to create a storefront.',
    }
  },
]} />

---

## Pass Personalized Data to the Order

If you followed the basic approach of using the `metadata` attribute to store the personalized data, you can pass the personalization data when you add an item to the cart in the storefront using the [Add a Line Item](https://docs.medusajs.com/api/store#carts_postcartscartlineitems) API Route. This API Route accepts a `metadata` request body parameter that will be stored in the created Line Item’s `metadata` attribute.

In the case that you’ve created a custom entity or extended a core entity, you can create a custom API Route that handles saving the personalization data. You can then call that API Route from the storefront before or after adding the item to the cart.

<DocCardList colSize={6} items={[
  {
    type: 'link',
    href: 'https://docs.medusajs.com/api/store#carts_postcartscartlineitems',
    label: 'Add a Line Item API Route',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn about the expected request parameters and response.',
    }
  },
  {
    type: 'link',
    href: '/development/api-routes/create',
    label: 'Create API Route',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to create an API Route in the Medusa backend.',
    }
  },
]} />

---

## Access Personalized Data in the Order

If you stored the personalized data in the `metadata` of the Line Items, those same Line Items are associated with the placed order. So, by expanding the `items` relation on the `Order` entity, you can retrieve the `metadata` attribute of the Line Items.

In the case that you’ve created a custom entity or extended a core entity, you can create a custom API Route that handles retrieving the personalization data. If the entity you’ve created or customized is associated with the Order entity, you can alternatively expand it similarly to the `items` relation.

If you want to show the personalized data in the Medusa admin, you can extend the Medusa admin to add a widget, a UI route, or a setting page and show the personalized data.

<DocCardList colSize={4} items={[
  {
    type: 'link',
    href: 'https://docs.medusajs.com/api/store#expanding-fields',
    label: 'Expanding Relations in API Requests',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to expand relations in API requests.',
    }
  },
  {
    type: 'link',
    href: '/development/services/create-service#pagination-filtering-and-relations',
    label: 'Expanding Relations in Services',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to expand relations in services.',
    }
  },
  {
    type: 'link',
    href: '/admin/widgets',
    label: 'Extending Medusa Admin',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to extend the Medusa admin with widgets and more.',
    }
  },
]} />

---

## Fulfill Personalized Products in Orders

Once a customer places an order, the `order.placed` event is emitted in the backend. You can listen to this event with a Subscriber to access the order’s details and fulfill its personalized products.

For example, if the customer personalizes a shirt to include an image or message, you can listen to the `order.placed` event to send their request to the printing fulfillment machine or service.

You can also listen to other [Order-related events](../development/events/events-list.md#order-events) to perform this action at a different point if necessary, such as when the `order.fulfillment_created` is triggered.

Alternatively, you can create a fulfillment service that integrates a third-party service or mechanism to fulfill the personalized product. This is useful if you want the fulfillment of personalized products to be embedded into Medusa’s existing order fulfillment.

<DocCardList colSize={6} items={[
  {
    type: 'link',
    href: '/development/events/create-subscriber',
    label: 'Create a Subscriber',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to create a subscriber and listen to events.',
    }
  },
  {
    type: 'link',
    href: '/modules/carts-and-checkout/backend/add-fulfillment-provider',
    label: 'Create a Fulfillment Service',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to create a fulfillment provider in Medusa.',
    }
  },
]} />

---

## Additional Development

You can find other resources for your personalized products development in the [Medusa Development section](../development/overview.mdx) of this documentation.
