docs: translation module (#14271)

* docs: translation module

* fix link in JS SDK

* add translations user guides [WIP]

* updates

* fix broken link

* remove mentions of default locale

* change header

* updates

* updated user guides

* handle todos

* fix build error

* fix lint errors
This commit is contained in:
Shahed Nasser
2025-12-17 13:07:43 +02:00
committed by GitHub
parent 1743ed7f04
commit c1a5390fc6
133 changed files with 21304 additions and 1661 deletions
@@ -6,7 +6,7 @@ products:
- cart
---
import { CodeTabs, CodeTab } from "docs-ui"
import { CodeTabs, CodeTab, Prerequisites } from "docs-ui"
export const metadata = {
title: `Create Cart in Storefront`,
@@ -132,6 +132,39 @@ However, if the cart is created for a guest customer, then the customer logs in,
---
## Set Cart's Locale
<Prerequisites
items={[
{
text: "Translation Module Configured",
link: "/commerce-modules/translation#configure-translation-module",
}
]}
/>
By default, items in the cart will have their associated product's original content. If your storefront supports [localization](../../localization/page.mdx), you can set the cart's locale to ensure that the item contents are in the customer's preferred language.
You can set the cart's locale by passing the `locale` request body parameter to the [Create Cart API route](!api!/store#carts_postcarts). For example:
```ts
sdk.store.cart.create({
region_id: region.id,
// you can also retrieve the locale from sdk.getLocale()
locale: "fr-FR",
})
.then(({ cart }) => {
// TODO use the cart...
console.log(cart)
})
```
When the cart's locale is set, the cart's items will have their content in the specified locale if translations are available.
You can also [update the cart's locale](../update/page.mdx#set-cart-locale) later if the customer changes their language preference.
---
## Store Cart Details in React Context
If you're using React, it's then recommended to create a context that stores the cart details and make it available to all components in your application, as explained in the [Cart React Context in Storefront](../context/page.mdx) guide.
@@ -7,7 +7,7 @@ products:
- customer
---
import { CodeTabs, CodeTab } from "docs-ui"
import { CodeTabs, CodeTab, Prerequisites } from "docs-ui"
export const metadata = {
title: `Update Cart in Storefront`,
@@ -86,3 +86,33 @@ Learn more about authenticating customers with the JS SDK in the [Login Customer
When using the Fetch API to send the request, either use `credentials: include` if the customer is already authenticated with a cookie session, or pass the Authorization Bearer token in the request's header.
</Note>
---
## Set Cart's Locale
<Prerequisites
items={[
{
text: "Translation Module Configured",
link: "/commerce-modules/translation#configure-translation-module",
}
]}
/>
By default, items in the cart will have their associated product's original content. If your storefront supports [localization](../../localization/page.mdx), you can set the cart's locale to ensure that the item contents are in the customer's preferred language.
You can set the cart's locale by passing the `locale` request body parameter to the [Update Cart API route](!api!/store#carts_postcarts). For example:
```ts
sdk.store.cart.update(cartId, {
// you can also retrieve the locale from sdk.getLocale()
locale: "fr-FR",
})
.then(({ cart }) => {
// TODO use the cart...
console.log(cart)
})
```
When the cart's locale is set, existing and new items in the cart will have their content in the specified locale if translations are available.
@@ -10,7 +10,7 @@ products:
- payment
---
import { CodeTabs, CodeTab } from "docs-ui"
import { CodeTabs, CodeTab, Prerequisites } from "docs-ui"
export const metadata = {
title: `Checkout Step 5: Complete Cart`,
@@ -57,6 +57,23 @@ When the cart completion is successful, it's important to unset the cart ID from
---
## Order's Locale after Cart Completion
<Prerequisites
items={[
{
text: "Translation Module Configured",
link: "/commerce-modules/translation#configure-translation-module",
}
]}
/>
When you complete the cart, items in the order will be in the locale that was set for the cart. This ensures that the customer sees the order details in their preferred language.
If no locale was set for the cart, then the order's items will be in the original product content.
---
## React Example with Default System Payment Provider
For example, to complete the cart when the default system payment provider is used:
@@ -6,7 +6,7 @@ products:
- order
---
import { CodeTabs, CodeTab, Table } from "docs-ui"
import { CodeTabs, CodeTab, Table, Prerequisites } from "docs-ui"
export const metadata = {
title: `Order Confirmation in Storefront`,
@@ -144,6 +144,21 @@ return (
In the above example, you show the order items in a list, displaying the item's title, quantity, and unit price formatted with the `formatPrice` function.
### Locale of Order Items
<Prerequisites
items={[
{
text: "Translation Module Configured",
link: "/commerce-modules/translation#configure-translation-module",
}
]}
/>
When you complete the cart, items in the order will be in the locale that was set for the cart. This ensures that the customer sees the order details in their preferred language.
If no locale was set for the cart, then the order's items will be in the original product content.
---
## Show Order Totals
@@ -0,0 +1,231 @@
---
tags:
- translation
- storefront
products:
- translation
---
import { Prerequisites, CodeTabs, CodeTab } from "docs-ui"
export const metadata = {
title: `Storefront Localization`,
}
# {metadata.title}
In this guide, you'll learn how to support multiple languages and locales in your storefront.
<Prerequisites
items={[
{
text: "Translation Module Configured",
link: "/commerce-modules/translation#configure-translation-module",
}
]}
/>
## Overview
Medusa provides localization features through the [Translation Module](../../commerce-modules/translation/page.mdx). The Translation Module allows you to manage locales and translations for various resources in your store, such as products and categories.
Admin users can [specify supported locales](!user-guide!/settings/store#manage-store-locales), and [add translations for different resources](!user-guide!/settings/translations) from the Medusa Admin. Then, you can allow customers to choose their locale and show them translated content in your storefront.
Refer to the [Translation Module documentation](../../commerce-modules/translation/page.mdx) to learn more about translation concepts and features. This guide focuses on how to serve localized content in your storefront.
---
## Retrieve Supported Locales
You can retrieve the list of locales supported by your store using the [List Locales Store API route](!api!/store#locales_getlocales). You can display this list to customers, allowing them to select their preferred language.
For example:
<Note title="Tip">
Learn how to install and configure the JS SDK in the [JS SDK documentation](../../js-sdk/page.mdx).
</Note>
<CodeTabs group="store-request">
<CodeTab label="React" value="react">
export const highlights = [
["18"], ["19"], ["20"], ["21"], ["22"]
]
```tsx highlights={highlights}
"use client" // include with Next.js 13+
import { useEffect, useState } from "react"
import { HttpTypes } from "@medusajs/types"
import { sdk } from "@/lib/sdk"
export default function Locales() {
const [loading, setLoading] = useState(true)
const [locales, setLocales] = useState<
HttpTypes.StoreLocale[]
>([])
useEffect(() => {
if (!loading) {
return
}
sdk.store.locale.list()
.then(({ locales: dataLocales }) => {
setLocales(dataLocales)
setLoading(false)
})
}, [loading])
return (
<div>
{loading && <span>Loading...</span>}
{!loading && locales.length === 0 && <span>No locales found.</span>}
{!loading && locales.length > 0 && (
<ul>
{locales.map((locale) => (
<li key={locale.code}>{locale.name}</li>
))}
</ul>
)}
</div>
)
}
```
</CodeTab>
<CodeTab label="JS SDK" value="js-sdk">
```ts
sdk.store.locale.list()
.then(({ locales: dataLocales }) => {
// TODO use locales...
console.log(dataLocales)
})
```
</CodeTab>
</CodeTabs>
The response has a `locales` field, which is an array of [locales](!api!/store#locales_locale_schema).
Each locale has a `code` property that follows the [IETF BCP 47 standard](https://gist.github.com/typpo/b2b828a35e683b9bf8db91b5404f1bd1). For example, `en-US` represents American English, while `fr-FR` represents French (France).
---
## Retrieve Translations for Resources
Currently, you can retrieve translations using the [Store API routes](!api!/store) for product-related resources, such as products, product variants, and categories. Future releases will expand translation support to additional resources.
By default, Medusa serves the original content of a resource. You can override the locale for a request to get the translated content if available.
### Set Locale in JS SDK
The JS SDK has a `setLocale` method that you can use to set the locale for subsequent requests.
The JS SDK will automatically include the `x-medusa-locale` header in API requests. Also, if your application supports `localStorage`, the method sets the locale in the `medusa_locale` key of the `localStorage`.
For example, when a customer selects a locale in your storefront, you can set the locale in the JS SDK:
```ts
sdk.setLocale("fr-FR")
// products content is fetched in French
const { products } = await sdk.store.product.list()
```
In the above example, you set the locale to French using the `setLocale` method. It accepts the locale string in the [IETF BCP 47 standard](https://gist.github.com/typpo/b2b828a35e683b9bf8db91b5404f1bd1).
When you fetch the products, their content, such as title and description, is in French and falls back to the original content if translations aren't available.
You can also retrieve the currently set locale using the `getLocale` method:
```ts
const currentLocale = sdk.getLocale()
console.log(currentLocale) // "fr-FR"
```
### Set Locale without JS SDK
If you're sending requests to the Store API without using the JS SDK, you can set the locale using either the `locale` query parameter or the `x-medusa-locale` header.
<CodeTabs group="set-locale">
<CodeTab label="Using Query Parameter" value="query-param">
```bash
curl "http://localhost:9000/store/products?locale=fr-FR" \
-H 'x-publishable-api-key: {your_publishable_api_key}'
```
</CodeTab>
<CodeTab label="Using Header" value="header">
```bash
curl "http://localhost:9000/store/products" \
-H 'x-publishable-api-key: {your_publishable_api_key}' \
-H "x-medusa-locale: fr-FR"
```
</CodeTab>
</CodeTabs>
Learn more in the [Store API reference](!api!/store#localization).
### Set Locale in Server Environments
If you're making Store API requests from a server environment (such as server components or server actions in Next.js), you can use cookies to persist the selected locale across requests.
When a customer selects a locale in your storefront, set a cookie (for example, `_medusa_locale`) with the selected locale value:
```ts
import { cookies } from "next/headers"
export const setLocale = async (locale: string) => {
const cookies_ = await cookies()
cookies_.set("_medusa_locale", locale, {
maxAge: 60 * 60 * 24 * 7,
})
}
```
Then, create a utility that returns the locale from the cookie as a `x-medusa-locale` header:
```ts
import { cookies } from "next/headers"
export const getLocaleHeader = async () => {
try {
const cookies_ = await cookies()
const locale = cookies_.get("_medusa_locale")?.value
return { "x-medusa-locale": locale }
} catch {
return {}
}
}
```
Finally, use the utility to set the `x-medusa-locale` header in your Store API requests:
```ts
import { getLocaleHeader } from "@/lib/locale"
export async function listProducts() {
const headers = {
...(await getLocaleHeader()),
}
return sdk.store.product.list({}, { headers })
}
```
### Retrieve Translated Products
When you pass the locale while fetching products, their content will be in the specified locale if translations are available. Learn more in the [List Products](../products/list/page.mdx) guide.
### Set Cart's Locale
When creating a cart, you should set the cart's locale to ensure that item contents are in the correct language. You can also update the cart's locale later if the customer changes their language preference.
Learn more in the [Create Cart](../cart/create/page.mdx) and [Update Cart](../cart/update/page.mdx) guides.
@@ -6,7 +6,7 @@ products:
- product
---
import { CodeTabs, CodeTab } from "docs-ui"
import { CodeTabs, CodeTab, Prerequisites } from "docs-ui"
export const metadata = {
title: `Show Products in Storefront`,
@@ -225,3 +225,82 @@ sdk.store.product.list({
```
The result will be products sorted by title in descending order.
---
## Retrieve Translations for Products
<Prerequisites
items={[
{
text: "Translation Module Configured",
link: "/commerce-modules/translation#configure-translation-module",
}
]}
/>
By default, Medusa returns the product's original content (such as title and description).
If you support [localization](../../localization/page.mdx) in your storefront, you can set the locale to retrieve product information with based on the customer's preferred language.
You can set the locale using one of the following methods:
- Use the JS SDK's `setLocale` method. The JS SDK will automatically include the locale in subsequent requests.
- Pass the `locale` query parameter to the [List Products API route](!api!/store#products_getproducts).
- Set the `x-medusa-locale` header in the API request to the [List Products API route](!api!/store#products_getproducts).
For example:
<CodeTabs group="localized-products">
<CodeTab label="Using JS SDK" value="js-sdk">
```ts
sdk.setLocale("fr-FR")
sdk.store.product.list()
.then(({ products: dataProducts, count }) => {
// TODO set products...
})
```
</CodeTab>
<CodeTab label="Using Query Parameter" value="query-param">
```bash
curl "http://localhost:9000/store/products?locale=fr-FR" \
-H 'x-publishable-api-key: {your_publishable_api_key}'
```
</CodeTab>
<CodeTab label="Using Header" value="header">
```bash
curl "http://localhost:9000/store/products" \
-H 'x-publishable-api-key: {your_publishable_api_key}' \
-H "x-medusa-locale: fr-FR"
```
</CodeTab>
</CodeTabs>
The returned products will have the same structure as described in the [products schema](!api!/store#products_product_schema), but their fields like `title` and `description` will be in the specified locale:
```json
{
"products": [
{
"id": "prod_123",
"title": "Chemise Exemple",
"description": "Ceci est une description en français.",
// other product fields...
}
]
}
```
If translations aren't available for the selected locale, or no locale is selected, the product's original content is returned.
### Retrieve in Server-Side Environments
For server-side environments (such as server components or server actions in Next.js), you can set the locale using cookies to persist the selected locale across requests.
Learn more in the [Storefront Localization](../../localization/page.mdx#set-locale-in-server-environments) guide.
@@ -6,7 +6,7 @@ products:
- product
---
import { CodeTabs, CodeTab } from "docs-ui"
import { CodeTabs, CodeTab, Prerequisites } from "docs-ui"
export const metadata = {
title: `Retrieve a Product in Storefront`,
@@ -70,7 +70,7 @@ export const highlights = [
setProduct(dataProduct)
setLoading(false)
})
}, [loading])
}, [loading, id])
return (
<div>
@@ -93,7 +93,7 @@ export const highlights = [
</ul>
)}
{product.images?.map((image) => (
<img src={image.url} key={image.id} />
<img src={image.url} alt={product.title} key={image.id} />
))}
</>
)}
@@ -132,7 +132,7 @@ Refer to the [Features in Product Details Page](#features-in-product-details-pag
## Retrieve a Product by Handle
To retrieve a product by its handle, send a request to the [List Products API route](!api!/store#products_getproducts) passing it the `handle` query parameter:
To retrieve a product by its handle, send a request to the [List Products API route](!api!/store#products_getproducts) passing the `handle` query parameter:
<CodeTabs group="store-request">
<CodeTab label="React" value="react">
@@ -174,7 +174,7 @@ export const handleHighlights = [
}
setLoading(false)
})
}, [loading])
}, [loading, handle])
return (
<div>
@@ -190,7 +190,7 @@ export const handleHighlights = [
{option.title}
<ul>
{option.values?.map((optionValue) => (
<li id={optionValue.id}>{optionValue.value}</li>
<li key={optionValue.id}>{optionValue.value}</li>
))}
</ul>
</li>
@@ -198,7 +198,7 @@ export const handleHighlights = [
</ul>
)}
{product.images?.map((image) => (
<img src={image.url} key={image.id} />
<img src={image.url} alt={product.title} key={image.id} />
))}
</>
)}
@@ -220,7 +220,7 @@ export const handleFetchHighlights = [
})
.then(({ products }) => {
if (!products.length) {
// product with the specified handle doesn't exist
// Product not found with the specified handle
return
}
// use the product...
@@ -233,11 +233,87 @@ export const handleFetchHighlights = [
---
## Retrieve Translated Product
<Prerequisites
items={[
{
text: "Translation Module Configured",
link: "/commerce-modules/translation#configure-translation-module",
}
]}
/>
By default, Medusa returns the product's original content (such as title and description).
If you support [localization](../../localization/page.mdx) in your storefront, you can set the locale to retrieve product information based on the customer's preferred language.
You can set the locale using one of the following methods:
- Use the JS SDK's `setLocale` method. The JS SDK will automatically include the locale in subsequent requests.
- Pass the `locale` query parameter to the [List Products API route](!api!/store#products_getproducts).
- Set the `x-medusa-locale` header in the API request to the [List Products API route](!api!/store#products_getproducts).
For example:
<CodeTabs group="localized-products">
<CodeTab label="Using JS SDK" value="js-sdk">
```ts
sdk.setLocale("fr-FR")
sdk.store.product.retrieve(id)
.then(({ product }) => {
// TODO use the product...
console.log(product)
})
```
</CodeTab>
<CodeTab label="Using Query Parameter" value="query-param">
```bash
curl "http://localhost:9000/store/products/prod_123?locale=fr-FR" \
-H 'x-publishable-api-key: {your_publishable_api_key}'
```
</CodeTab>
<CodeTab label="Using Header" value="header">
```bash
curl "http://localhost:9000/store/products/prod_123" \
-H 'x-publishable-api-key: {your_publishable_api_key}' \
-H "x-medusa-locale: fr-FR"
```
</CodeTab>
</CodeTabs>
The returned product will have the same structure as described in the [products schema](!api!/store#products_product_schema), but fields such as `title` and `description` will be in the specified locale:
```json
{
"id": "prod_123",
"title": "Chemise Exemple",
"description": "Ceci est une description en français.",
// other product fields...
}
```
If translations aren't available for the selected locale, or no locale is selected, the product's original content is returned.
### Retrieve in Server-Side Environments
For server-side environments (such as server components or server actions in Next.js), you can set the locale using cookies to persist the selected locale across requests.
Learn more in the [Storefront Localization](../../localization/page.mdx#set-locale-in-server-environments) guide.
---
## Features in Product Details Page
In a product's details page, you want to allow the customer to choose a variant, see its price, and add it to the cart.
On a product details page, you typically want to allow customers to choose a variant, see its price, and add it to the cart.
The following guides will help you add these features into your storefront:
The following guides will help you add these features to your storefront:
- [Select a variant](../variants/page.mdx)
- [Show variant price](../price/page.mdx)