docs: update docs across projects following publishable API key change in store routes (#9098)

* docs: update docs across projects following publishable API key change in store routes

* rename env variable

* move subscribe route out of store
This commit is contained in:
Shahed Nasser authored and GitHub committed 2024-09-16 16:42:08 +03:00
1 parent ef8dc4087e
commit 58f06be44d
66 files changed
+577 -298

No files matched your search

@@ -2268,6 +2268,9 @@ export const getDigitalProductPreview = cache(async function ({
const { previews } = await fetch(
`${process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL}/store/digital-products/${id}/preview`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}).then((res) => res.json())
// for simplicity, return only the first preview url
@@ -2378,6 +2381,7 @@ export const getCustomerDigitalProducts = async () => {
credentials: "include",
headers: {
...getAuthHeaders(),
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}).then((res) => res.json())
@@ -2536,6 +2540,7 @@ export const getDigitalMediaDownloadLink = async (mediaId: string) => {
method: "POST",
headers: {
...getAuthHeaders(),
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}).then((res) => res.json())
@@ -57,6 +57,10 @@ This recipe is adapted from [Medusa Eats](https://github.com/medusajs/medusa-eat
text: "A new Medusa application installed.",
link: "!docs!#get-started"
},
{
text: "Publishable API key to send store requests. You can create it in the Medusa Admin or using the Admin API routes",
link: "/storefront-development/publishable-api-keys"
},
{
text: "Recommended: Use the Redis Workflow Engine Module for improved tracking and storage of workflow executions."
}
@@ -2134,6 +2138,7 @@ Before using the API route, you must have a cart with at least one product from
```bash
curl -X POST 'http://localhost:9000/store/carts' \
-H 'Content-Type: application/json' \
-H 'x-publishable-api-key: {your_publishable_api_key}' \
--data-raw '{
"region_id": "reg_01J66SWSSWFZPQV0GWR2W7P1SB",
"sales_channel_id": "sc_01J66SWSRK95F2P2KTFHMYR7VC",
@@ -2164,6 +2169,7 @@ curl -X POST 'http://localhost:9000/store/carts' \
```bash
curl -X POST 'http://localhost:9000/store/carts/cart_01J67MS5WPH2CE5R84BENJCGSW/line-items' \
-H 'Content-Type: application/json' \
-H 'x-publishable-api-key: {your_publishable_api_key}' \
--data-raw '{
"variant_id": "variant_01J66T0VC2S0NB4BNDBCZN8P9F",
"quantity": 1
@@ -2176,6 +2182,7 @@ curl -X POST 'http://localhost:9000/store/carts/cart_01J67MS5WPH2CE5R84BENJCGSW/
```bash
curl 'http://localhost:9000/store/shipping-options?cart_id=cart_01J67JT10B3RCWKT9NFEFYA2XG' \
-H 'x-publishable-api-key: {your_publishable_api_key}'
```
Make sure to replace the value of the `cart_id` query parameter with the cart’s ID.
@@ -2185,6 +2192,7 @@ curl 'http://localhost:9000/store/shipping-options?cart_id=cart_01J67JT10B3RCWKT
```bash
curl -X POST 'http://localhost:9000/store/carts/cart_01J67MS5WPH2CE5R84BENJCGSW/shipping-methods' \
-H 'Content-Type: application/json' \
-H 'x-publishable-api-key: {your_publishable_api_key}' \
--data-raw '{
"option_id": "so_01J66SWSVQG7S1BSJKR7PYWH6C",
"data": {}
@@ -2198,6 +2206,7 @@ curl -X POST 'http://localhost:9000/store/carts/cart_01J67MS5WPH2CE5R84BENJCGSW/
```bash
curl -X POST 'http://localhost:9000/store/payment-collections' \
-H 'Content-Type: application/json' \
-H 'x-publishable-api-key: {your_publishable_api_key}' \
--data-raw '{
"cart_id": "cart_01J67MS5WPH2CE5R84BENJCGSW"
}'
@@ -2210,6 +2219,7 @@ curl -X POST 'http://localhost:9000/store/payment-collections' \
```bash
curl -X POST 'http://localhost:9000/store/payment-collections/pay_col_01J67MSK397M3BKD3RDVDMJSRE/payment-sessions' \
-H 'Content-Type: application/json' \
-H 'x-publishable-api-key: {your_publishable_api_key}' \
--data-raw '{
"provider_id": "pp_system_default"
}'
@@ -2227,6 +2237,7 @@ Then, send a `POST` request to `/store/deliveries` to create the order delivery:
```bash
curl -X POST 'http://localhost:9000/store/deliveries' \
-H 'Content-Type: application/json' \
-H 'x-publishable-api-key: {your_publishable_api_key}' \
--data '{
"cart_id": "cart_01J67MS5WPH2CE5R84BENJCGSW",
"restaurant_id": "res_01J66SYN5DSRR0R6QM3A4SYRFZ"
@@ -3256,9 +3267,9 @@ In this step, you’ll learn how to implement real-time tracking of a delivery i
Before adding the storefront UI, you need an API route that allows a client to stream delivery changes.
So, create the file `src/api/store/deliveries/subscribe/route.ts` with the following content:
So, create the file `src/api/deliveries/subscribe/route.ts` with the following content:
```ts title="src/api/store/deliveries/subscribe/route.ts" collapsibleLines="1-12" expandButtonLabel="Show Imports"
```ts title="src/api/deliveries/subscribe/route.ts" collapsibleLines="1-12" expandButtonLabel="Show Imports"
import {
MedusaRequest,
MedusaResponse,
@@ -3287,11 +3298,11 @@ export const GET = async (
}
```
This creates a `GET` API route at `/store/deliveries/[id]/subscribe`. Currently, you only retrieve the delivery by its ID.
This creates a `GET` API route at `/deliveries/[id]/subscribe`. Currently, you only retrieve the delivery by its ID.
Next, you’ll stream the changes in the delivery. To do that, replace the `TODO` with the following:
```ts title="src/api/store/deliveries/subscribe/route.ts"
```ts title="src/api/deliveries/subscribe/route.ts"
const headers = {
"Content-Type": "text/event-stream",
Connection: "keep-alive",
@@ -3316,7 +3327,7 @@ In the above snippet, you set the response to a stream and write an initial mess
To listen to the workflow changes, replace the new `TODO` with the following:
```ts title="src/api/store/deliveries/subscribe/route.ts"
```ts title="src/api/deliveries/subscribe/route.ts"
const workflowEngine = req.scope.resolve(
Modules.WORKFLOW_ENGINE
)
@@ -3338,9 +3349,9 @@ In this snippet, you resolve the Workflow Engine Module’s main service. Then,
The storefront UI will also need to retrieve the delivery. So, you’ll create an API route that retrieves the delivery’s details.
Create the file `src/api/store/deliveries/[id]/route.ts` with the following content:
Create the file `src/api/deliveries/[id]/route.ts` with the following content:
```ts title="src/api/store/deliveries/[id]/route.ts"
```ts title="src/api/deliveries/[id]/route.ts"
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
import { DELIVERY_MODULE } from "../../../../modules/delivery"
@@ -3405,6 +3416,9 @@ To retrieve the delivery from the Medusa application, replace the first `TODO` w
// retrieve the delivery
fetch(`http://localhost:9000/store/deliveries/${id}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK,
},
})
.then((res) => res.json())
.then((data) => {
@@ -3420,7 +3434,7 @@ Next, to subscribe to the delivery’s changes in real-time, replace the remaini
```tsx title="Storefront Page"
// subscribe to the delivery updates
const source = new EventSource(
`http://localhost:9000/store/deliveries/${id}/subscribe`
`http://localhost:9000/deliveries/${id}/subscribe`
)
source.onmessage = (message) => {
@@ -3442,7 +3456,7 @@ return () => {
}
```
You use the [EventSource API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) to receive the stream from the `/store/deliveries/[id]/subscribe` API route.
You use the [EventSource API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) to receive the stream from the `/deliveries/[id]/subscribe` API route.
When a new message is set, the new delivery update is extracted from `message.data.response`, if `response` is available and has a `delivery_status` property.
@@ -28,6 +28,7 @@ For example, if you’re asking customers to enter a message to put in a letter
```bash
curl -X POST '{backend_url}/store/carts/{id}/line-items' \
-H 'Content-Type: application/json' \
-H 'x-publishable-api-key: {your_publishable_api_key}' \
--data-raw '{
"variant_id": "variant_123",
"quantity": 1,
@@ -2234,7 +2234,8 @@ Then, send a `GET` request to `/store/customers/me/subscriptions` to retrieve th
```bash
curl 'http://localhost:9000/store/customers/me/subscriptions' \
-H 'Authorization: Bearer {token}'
-H 'Authorization: Bearer {token}' \
-H 'x-publishable-api-key: {your_publishable_api_key}'
```
Where `{token}` is the token retrieved from the previous request.
@@ -2243,7 +2244,8 @@ To cancel a subscription, send a `POST` request to `/store/customers/me/subscrip
```bash
curl -X POST 'http://localhost:9000/store/customers/me/subscriptions/01J2VB8TVC14K29FREQ2DRS6NA' \
-H 'Authorization: Bearer {token}'
-H 'Authorization: Bearer {token}' \
-H 'x-publishable-api-key: {your_publishable_api_key}'
```
---
@@ -22,10 +22,10 @@ export const highlights = [
["32", "useRegion", "Use the `useRegion` hook defined in the Region Context guide."],
["37", "setItem", "Set the cart's ID in `localStorage` in case it changed."],
["45", "fetch", "If the customer doesn't have a cart, create a new one."],
["49", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to associate the correct sales channel(s)."],
["49", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to associate the correct sales channel(s)."],
["63", "fetch", "Retrieve the customer's cart."],
["73", "refreshCart", "This function unsets the cart, which triggers the `useEffect` callback to create a cart."],
["89", "useCart", "The hook that child components of the provider use to access the cart."]
["76", "refreshCart", "This function unsets the cart, which triggers the `useEffect` callback to create a cart."],
["92", "useCart", "The hook that child components of the provider use to access the cart."]
]
```tsx highlights={highlights}
@@ -72,7 +72,7 @@ export const CartProvider = ({ children }: CartProviderProps) => {
method: "POST",
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
@@ -88,6 +88,9 @@ export const CartProvider = ({ children }: CartProviderProps) => {
// retrieve cart
fetch(`http://localhost:9000/store/carts/${cartId}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ cart: dataCart }) => {
@@ -20,7 +20,7 @@ For example:
<CodeTab label="Fetch API" value="fetch">
export const fetchHighlights = [
["5", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to associate the correct sales channel(s)."],
["5", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to associate the correct sales channel(s)."],
["9", "region_id", "Associate the cart with the chosen region for accurate pricing."],
["14", "setItem", "Set the cart's ID in the `localStorage`."]
]
@@ -30,7 +30,7 @@ export const fetchHighlights = [
method: "POST",
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
@@ -50,7 +50,7 @@ export const highlights = [
["8", "region", "Assuming you previously retrieved the chosen region."],
["15", "cartId", "Retrieve the cart ID from `localStorage`, if exists."],
["21", "", "Send a request to create the cart."],
["26", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to associate the correct sales channel(s)."],
["26", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to associate the correct sales channel(s)."],
["30", "region_id", "Associate the cart with the chosen region for accurate pricing."],
["35", "setItem", "Set the cart's ID in the `localStorage`."]
]
@@ -81,7 +81,7 @@ export const highlights = [
method: "POST",
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
@@ -19,7 +19,8 @@ For example:
export const addHighlights = [
["1", "variant_id", "The ID of the selected variant."],
["2", "cartId", "Retrieve the cart ID from the `localStorage`."],
["16", "quantity", "You can also allow customers to specify the quantity."]
["13", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "You must pass the publishable API key of all storefront requests."],
["17", "quantity", "You can also allow customers to specify the quantity."]
]
```ts highlights={addHighlights}
@@ -35,6 +36,7 @@ const addToCart = (variant_id: string) => {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
variant_id,
@@ -70,6 +72,7 @@ export const updateHighlights = [
["3", "quantity", "The new quantity of the item."],
["5", "cartId", "Retrieve the cart ID from the `localStorage`."],
["12", "itemId", "Pass the item's ID as a path parameter."],
["18", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "You must pass the publishable API key of all storefront requests."],
]
```ts highlights={updateHighlights}
@@ -90,6 +93,7 @@ const updateQuantity = (
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
quantity,
@@ -122,7 +126,8 @@ export const deleteHighlights = [
["1", "itemId", "The ID of the line item to remove."],
["2", "cartId", "Retrieve the cart ID from the `localStorage`."],
["9", "itemId", "Pass the item's ID as a path parameter."],
["15", "parent", "The updated cart is returned as the `parent` field."]
["13", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "You must pass the publishable API key of all storefront requests."],
["18", "parent", "The updated cart is returned as the `parent` field."]
]
```ts highlights={deleteHighlights}
@@ -137,6 +142,9 @@ const removeItem = (itemId: string) => {
itemId
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
method: "DELETE",
})
.then((res) => res.json())
@@ -22,6 +22,9 @@ export const fetchHighlights = [
```ts highlights={fetchHighlights}
fetch(`http://localhost:9000/store/carts/${cartId}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ cart }) => {
@@ -37,8 +40,8 @@ export const highlights = [
["16", "cartId", "Retrieve the cart ID from `localStorage`."],
["18", "TODO", "You can create the cart and set it here as explained in the Create Cart guide."],
["22"], ["23"], ["24"], ["25"], ["26"], ["27"], ["28"],
["31", "formatPrice", "This function was previously created to format product prices. You can re-use the same function."],
["34", "currency_code", "If you reuse the `formatPrice` function, pass the currency code as a parameter."],
["34", "formatPrice", "This function was previously created to format product prices. You can re-use the same function."],
["37", "currency_code", "If you reuse the `formatPrice` function, pass the currency code as a parameter."],
]
```tsx highlights={highlights}
@@ -65,6 +68,9 @@ export const highlights = [
fetch(`http://localhost:9000/store/carts/${cartId}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ cart: dataCart }) => {
@@ -21,7 +21,7 @@ If a customer changes their region, you must update their cart to be associated
For example:
export const updateRegionHighlights = [
["8", `"new_id"`, "Pass the new chosen region's ID."]
["11", `"new_id"`, "Pass the new chosen region's ID."]
]
```ts highlights={updateRegionHighlights}
@@ -30,6 +30,9 @@ fetch(`http://localhost:9000/store/carts/${cartId}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
},
body: JSON.stringify({
region_id: "new_id",
@@ -53,7 +56,7 @@ If a guest customer logs in, you must update the cart to be associated with the
For example:
export const updateCustomerHighlights = [
["8", `"logged_in_id"`, "Pass the logged-in customer's ID."]
["11", `"logged_in_id"`, "Pass the logged-in customer's ID."]
]
```ts highlights={updateCustomerHighlights}
@@ -62,6 +65,9 @@ fetch(`http://localhost:9000/store/carts/${cartId}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
},
body: JSON.stringify({
customer_id: "logged_in_id",
@@ -37,6 +37,7 @@ For example:
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
shipping_address: address,
@@ -57,8 +58,8 @@ export const highlights = [
["4", "useCart", "The `useCart` hook was defined in the Cart React Context documentation."],
["29", "address", "Assemble the address object to be used for both shipping and billing addresses."],
["41"], ["42"], ["43"], ["44"], ["45"], ["46"], ["47"], ["48"],
["49"], ["50"], ["51"], ["52"], ["53"], ["54"], ["55"],
["102", "", "The address's country can only be within the cart's region."]
["49"], ["50"], ["51"], ["52"], ["53"], ["54"], ["55"], ["56"]
["103", "", "The address's country can only be within the cart's region."]
]
```tsx highlights={highlights}
@@ -107,6 +108,7 @@ export const highlights = [
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
shipping_address: address,
@@ -17,6 +17,9 @@ fetch(
`http://localhost:9000/store/carts/${cartId}/complete`,
{
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
method: "POST",
}
)
@@ -53,10 +56,10 @@ export const highlights = [
["10", "handlePayment", "This function sends the request\nto the Medusa application to complete the cart."],
["21", "TODO", "If you're integrating a third-party payment provider,\nyou perform the custom logic before completing the cart."],
["24", "fetch", "Send a request to the Medusa application\nto complete the cart and place the order."],
["33", `type === "cart"`, "If the `type` returned is `cart`,\nit means an error occurred and the cart wasn't completed."],
["36", `type === "order"`, "If the `type` returned is `order`,\nit means the cart was completed and the order was placed successfully."],
["40", "refreshCart", "Unset and reset the cart."],
["47", "button", "This button triggers the `handlePayment` function when clicked."]
["36", `type === "cart"`, "If the `type` returned is `cart`,\nit means an error occurred and the cart wasn't completed."],
["39", `type === "order"`, "If the `type` returned is `order`,\nit means the cart was completed and the order was placed successfully."],
["43", "refreshCart", "Unset and reset the cart."],
["50", "button", "This button triggers the `handlePayment` function when clicked."]
]
```tsx highlights={highlights}
@@ -87,6 +90,9 @@ export default function SystemDefaultPayment() {
`http://localhost:9000/store/carts/${cart.id}/complete`,
{
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
method: "POST",
}
)
@@ -27,6 +27,7 @@ For example:
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
email,
@@ -46,7 +47,7 @@ export const highlights = [
["4", "useCart", "The `useCart` hook was defined in the Cart React Context documentation."],
["13", "TODO", "Cart must have at least one item. If not, redirect to another page."],
["27"], ["28"], ["29"], ["30"], ["31"], ["32"], ["33"], ["34"],
["35"], ["36"], ["37"], ["38"], ["39"], ["40"]
["35"], ["36"], ["37"], ["38"], ["39"], ["40"], ["41"]
]
```tsx highlights={highlights}
@@ -81,6 +82,7 @@ export const highlights = [
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
email,
@@ -34,17 +34,17 @@ For example, to implement the payment step flow:
export const fetchHighlights = [
["6", "retrievePaymentProviders", "This function retrieves the payment provider that the customer can choose from."],
["7", "fetch", "Retrieve available payment providers."],
["18", "selectPaymentProvider", "This function is executed when the customer submits their chosen payment provider."],
["25", "fetch", "Create a payment collection for the cart when it doesn't have one."],
["44", "fetch", "Initialize the payment session in the payment collection for the chosen provider."],
["62", "fetch", "Retrieve the cart again to update its data."],
["73", "getPaymentUi", "This function shows the necessary UI based on the selected payment provider."],
["74", "activePaymentSession", "The active session is the first in the payment collection's sessions."],
["80", "", "Test which payment provider is chosen based on the prefix of the provider ID."],
["81", `"pp_stripe_"`, "Check if the chosen provider is Stripe."],
["85", `"pp_system_default"`, "Check if the chosen provider is the default systen provider."],
["87", "default", "Handle unrecognized providers."],
["94", "handlePayment", "The function that handles the payment process using the above functions."]
["21", "selectPaymentProvider", "This function is executed when the customer submits their chosen payment provider."],
["28", "fetch", "Create a payment collection for the cart when it doesn't have one."],
["48", "fetch", "Initialize the payment session in the payment collection for the chosen provider."],
["67", "fetch", "Retrieve the cart again to update its data."],
["81", "getPaymentUi", "This function shows the necessary UI based on the selected payment provider."],
["82", "activePaymentSession", "The active session is the first in the payment collection's sessions."],
["88", "", "Test which payment provider is chosen based on the prefix of the provider ID."],
["89", `"pp_stripe_"`, "Check if the chosen provider is Stripe."],
["93", `"pp_system_default"`, "Check if the chosen provider is the default systen provider."],
["95", "default", "Handle unrecognized providers."],
["102", "handlePayment", "The function that handles the payment process using the above functions."]
]
```ts highlights={fetchHighlights}
@@ -59,6 +59,9 @@ const retrievePaymentProviders = async () => {
cart.region_id
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -79,6 +82,7 @@ const selectPaymentProvider = async (
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
cart_id: cart.id,
@@ -99,6 +103,7 @@ const selectPaymentProvider = async (
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
provider_id: selectedPaymentProviderId,
@@ -113,6 +118,9 @@ const selectPaymentProvider = async (
`http://localhost:9000/store/carts/${cart.id}`,
{
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}
)
.then((res) => res.json())
@@ -159,18 +167,18 @@ const handlePayment = () => {
export const highlights = [
["4", "useCart", "The `useCart` hook was defined in the Cart React Context documentation."],
["23", "fetch", "Retrieve available payment providers."],
["31", "setSelectedPaymentProvider", "If a payment provider was selected before, pre-fill it."],
["37", "handleSelectProvider", "This function is executed when the customer submits their chosen payment provider."],
["50", "fetch", "Create a payment collection for the cart when it doesn't have one."],
["72", "fetch", "Initialize the payment session in the payment collection for the chosen provider."],
["90", "fetch", "Retrieve the cart again to update its data."],
["103", "getPaymentUi", "This function shows the necessary UI based on the selected payment provider."],
["104", "activePaymentSession", "The active session is the first in the payment collection's sessions."],
["110", "", "Test which payment provider is chosen based on the prefix of the provider ID."],
["111", `"pp_stripe_"`, "Check if the chosen provider is Stripe."],
["119", `"pp_system_default"`, "Check if the chosen provider is the default systen provider."],
["125", "default", "Handle unrecognized providers."],
["160", "getPaymentUi", "If a provider is chosen, render its UI."]
["34", "setSelectedPaymentProvider", "If a payment provider was selected before, pre-fill it."],
["40", "handleSelectProvider", "This function is executed when the customer submits their chosen payment provider."],
["53", "fetch", "Create a payment collection for the cart when it doesn't have one."],
["76", "fetch", "Initialize the payment session in the payment collection for the chosen provider."],
["95", "fetch", "Retrieve the cart again to update its data."],
["111", "getPaymentUi", "This function shows the necessary UI based on the selected payment provider."],
["112", "activePaymentSession", "The active session is the first in the payment collection's sessions."],
["118", "", "Test which payment provider is chosen based on the prefix of the provider ID."],
["119", `"pp_stripe_"`, "Check if the chosen provider is Stripe."],
["127", `"pp_system_default"`, "Check if the chosen provider is the default systen provider."],
["133", "default", "Handle unrecognized providers."],
["168", "getPaymentUi", "If a provider is chosen, render its UI."]
]
```tsx highlights={highlights}
@@ -200,6 +208,9 @@ export default function CheckoutPaymentStep() {
cart.region_id
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ payment_providers }) => {
@@ -231,6 +242,7 @@ export default function CheckoutPaymentStep() {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
cart_id: cart.id,
@@ -251,6 +263,7 @@ export default function CheckoutPaymentStep() {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
provider_id: selectedPaymentProvider,
@@ -265,6 +278,9 @@ export default function CheckoutPaymentStep() {
`http://localhost:9000/store/carts/${cart.id}`,
{
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}
)
.then((res) => res.json())
@@ -66,10 +66,10 @@ export const highlights = [
["61", "confirmCardPayment", "This function shows the UI to the customer to accept the card payment."],
["78", "", "Once the customer enters their card details and submits the form,\nthe Promise resolves and executes this function."],
["85", "fetch", "Send a request to the Medusa application\nto complete the cart and place the order."],
["94", `type === "cart"`, "If the `type` returned is `cart`,\nit means an error occurred and the cart wasn't completed."],
["97", `type === "order"`, "If the `type` returned is `order`,\nit means the cart was completed and the order was placed successfully."],
["101", "refreshCart", "Unset and reset the cart."],
["111", "button", "This button triggers the `handlePayment` function when clicked."]
["97", `type === "cart"`, "If the `type` returned is `cart`,\nit means an error occurred and the cart wasn't completed."],
["100", `type === "order"`, "If the `type` returned is `order`,\nit means the cart was completed and the order was placed successfully."],
["104", "refreshCart", "Unset and reset the cart."],
["114", "button", "This button triggers the `handlePayment` function when clicked."]
]
```tsx highlights={highlights}
@@ -161,6 +161,9 @@ const StripeForm = ({
`http://localhost:9000/store/carts/${cart.id}/complete`,
{
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
method: "POST",
}
)
@@ -20,8 +20,8 @@ For example:
export const fetchHighlights = [
["3", "retrieveShippingOptions", "This function retrieves the shipping options of the customer's cart."],
["16", "setShippingMethod", "This function sets the shipping method of the cart using the selected shipping option."],
["29", "data", "Pass in this property any data relevant to the fulfillment provider."],
["19", "setShippingMethod", "This function sets the shipping method of the cart using the selected shipping option."],
["33", "data", "Pass in this property any data relevant to the fulfillment provider."],
]
```ts highlights={fetchHighlights}
@@ -33,6 +33,9 @@ export const fetchHighlights = [
cart.id
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}
)
.then((res) => res.json())
@@ -50,6 +53,7 @@ export const fetchHighlights = [
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
option_id: selectedShippingOptionId,
@@ -73,8 +77,8 @@ export const fetchHighlights = [
export const highlights = [
["4", "useCart", "The `useCart` hook was defined in the Cart React Context documentation."],
["22", "fetch", "Retrieve available shipping method of the customer's cart."],
["43", "fetch", "Set the cart's shipping method using the selected shipping option."],
["53", "data", "Pass in this property any data relevant to the fulfillment provider."]
["46", "fetch", "Set the cart's shipping method using the selected shipping option."],
["57", "data", "Pass in this property any data relevant to the fulfillment provider."]
]
```tsx highlights={highlights}
@@ -103,6 +107,9 @@ export const highlights = [
cart.id
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ shipping_options }) => {
@@ -127,6 +134,7 @@ export const highlights = [
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
option_id: selectedShippingOption,
@@ -30,6 +30,9 @@ export const fetchHighlights = [
searchParams.toString()
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ addresses, count }) => {
@@ -44,11 +47,11 @@ export const fetchHighlights = [
export const highlights = [
["20", "offset", "Calculate the number of addresses to skip based on the current page and limit."],
["27", "fetch", "Send a request to retrieve the addresses."],
["28", "searchParams.toString()", "Pass the pagination parameters in the query."],
["33", "count", "The total number of addresses in the Medusa application."],
["45", "setHasMorePages", "Set whether there are more pages based on the total count."],
["59", "", "Using only two address fields for simplicity."],
["65", "button", "Show a button to load more addresses if there are more pages."]
["31", "searchParams.toString()", "Pass the pagination parameters in the query."],
["34", "count", "The total number of addresses in the Medusa application."],
["48", "setHasMorePages", "Set whether there are more pages based on the total count."],
["62", "", "Using only two address fields for simplicity."],
["68", "button", "Show a button to load more addresses if there are more pages."]
]
```tsx highlights={highlights} collapsibleLines="50-77" expandButtonLabel="Show render"
@@ -82,6 +85,9 @@ export const highlights = [
searchParams.toString()
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ addresses: addressesData, count }) => {
@@ -155,6 +161,7 @@ To add a new address for the customer, send a request to the [Add Customer Addre
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
first_name: firstName,
@@ -183,7 +190,7 @@ export const addHighlights = [
["5", "useCustomer", "Use the hook defined in the Customer Context guide."],
["28"], ["29"], ["30"], ["31"], ["32"], ["33"], ["34"], ["35"], ["36"], ["37"],
["38"], ["39"], ["40"], ["41"], ["42"], ["43"], ["44"], ["45"], ["46"], ["47"],
["48"], ["49"]
["48"], ["49"], ["50"]
]
```tsx highlights={addHighlights} collapsibleLines="53-124" expandButtonLabel="Show form"
@@ -219,6 +226,7 @@ export const addHighlights = [
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
first_name: firstName,
@@ -337,6 +345,7 @@ To edit an address, send a request to the [Update Customer Address API route](!a
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
first_name: firstName,
@@ -368,7 +377,7 @@ export const editHighlights = [
["19", "address", "Retrieve the address from the customer's `addresses` property."],
["60"], ["61"], ["62"], ["63"], ["64"], ["65"], ["66"], ["67"], ["68"], ["69"],
["70"], ["71"], ["72"], ["73"], ["74"], ["75"], ["76"], ["77"], ["78"], ["79"],
["80"], ["81"]
["80"], ["81"], ["82"]
]
```tsx highlights={editHighlights} collapsibleLines="90-161" expandButtonLabel="Show form"
@@ -440,6 +449,7 @@ export const editHighlights = [
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
first_name: firstName,
@@ -557,6 +567,9 @@ fetch(
}`,
{
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
method: "DELETE",
}
)
@@ -18,7 +18,7 @@ export const highlights = [
["24", "CustomerProvider", "The provider component to use in your component tree."],
["36", "fetch", "Try to retrieve the customer's details,\nif the customer is authentiated."],
["37", `credentials: "include"`, "Important to include this option for cookie session authentication.\nFor token authentication, pass the authorization header instead."],
["58", "useCustomer", "The hook that child components of the provider use to access the customer."]
["61", "useCustomer", "The hook that child components of the provider use to access the customer."]
]
```tsx highlights={highlights}
@@ -59,6 +59,9 @@ export const CustomerProvider = ({
fetch(`http://localhost:9000/store/customers/me`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ customer }) => {
@@ -45,12 +45,11 @@ For example:
export const highlights = [
["3", "useCustomer", "Use the hook defined in the Customer Context guide."],
["9"], ["10"], ["11"], ["12"], ["13"], ["14"], ["15"], ["16"], ["17"], ["18"],
["19"],
["9"], ["10"], ["11"], ["12"], ["13"], ["14"], ["15"], ["16"], ["17"], ["18"]
]
```tsx highlights={highlights}
"use client" // include with Next.js 13+
"use client" // include with Next.js 13+
import { useCustomer } from "../../../providers/customer"
@@ -51,6 +51,7 @@ export const fetchHighlights = [
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}
)
@@ -115,6 +116,7 @@ export const highlights = [
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}
)
@@ -221,6 +223,7 @@ export const fetchSessionHighlights = [
credentials: "include",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}
)
@@ -300,6 +303,7 @@ export const sessionHighlights = [
credentials: "include",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}
)
@@ -19,6 +19,7 @@ For example:
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
first_name,
@@ -40,7 +41,7 @@ For example:
export const highlights = [
["4", "useCustomer", "Use the hook defined in the Customer Context guide."],
["33"], ["34"], ["35"], ["36"], ["37"], ["38"], ["39"], ["40"], ["41"], ["42"],
["43"], ["44"], ["45"], ["46"], ["47"], ["48"], ["49"]
["43"], ["44"], ["45"], ["46"], ["47"], ["48"], ["49"], ["50"]
]
```tsx highlights={highlights} collapsibleLines="53-91" expandButtonLabel="Show form"
@@ -81,6 +82,7 @@ export const highlights = [
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
first_name: firstName,
@@ -21,7 +21,7 @@ export const fetchHighlights = [
["3", "fetch", "Send a request to obtain a JWT token."],
["20", "fetch", "Send a request to create the customer."],
["27", "token", "Pass as a Bearer token in the authorization header."],
["39", "TODO", "Redirect the customer to the log in page."]
["40", "TODO", "Redirect the customer to the log in page."]
]
```ts highlights={fetchHighlights}
@@ -52,6 +52,7 @@ export const fetchHighlights = [
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
first_name: firstName,
@@ -74,7 +75,7 @@ export const highlights = [
["22", "fetch", "Send a request to obtain a JWT token."],
["39", "fetch", "Send a request to create the customer."],
["46", "token", "Pass as a Bearer token in the authorization header."],
["59", "TODO", "Redirect the customer to the log in page."]
["60", "TODO", "Redirect the customer to the log in page."]
]
```tsx highlights={highlights} collapsibleLines="61-100" expandButtonLabel="Show form"
@@ -124,6 +125,7 @@ export const highlights = [
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
first_name: firstName,
@@ -23,6 +23,7 @@ export const bearerHighlights = [
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}
)
@@ -47,6 +48,7 @@ export const sessionHighlights = [
credentials: "include",
headers: {
"Content-Type": "application/json",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}
)
@@ -85,6 +85,7 @@ const loginWithGoogle = async () => {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${result.token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}
)
@@ -138,6 +139,7 @@ export default function Login() {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${result.token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
}
)
@@ -292,6 +294,7 @@ const createCustomer = async (token: string) => {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
// TODO show form to retrieve email from customer
@@ -364,6 +367,7 @@ const validateCallback = async () => {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
// TODO show form to retrieve email from customer
@@ -406,6 +410,7 @@ const validateCallback = async () => {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
// TODO show form to retrieve email from customer
@@ -481,6 +486,7 @@ const createCustomer = async (token: string) => {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
// TODO show form to retrieve email from customer
@@ -521,6 +527,7 @@ const validateCallback = async () => {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
// TODO show form to retrieve email from customer
@@ -575,6 +582,7 @@ export default function GoogleCallback() {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
// TODO show form to retrieve email from customer
@@ -615,6 +623,7 @@ export default function GoogleCallback() {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
body: JSON.stringify({
// TODO show form to retrieve email from customer
@@ -18,6 +18,9 @@ To retrieve the list of product categories, send a request to the [List Product
```ts
fetch(`http://localhost:9000/store/product-categories`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ product_categories }) => {
@@ -31,7 +34,8 @@ To retrieve the list of product categories, send a request to the [List Product
export const highlights = [
["17"], ["18"], ["19"], ["20"],
["21"], ["22"], ["23"], ["24"]
["21"], ["22"], ["23"], ["24"],
["25"], ["26"], ["27"]
]
```tsx highlights={highlights}
@@ -53,6 +57,9 @@ export const highlights = [
fetch(`http://localhost:9000/store/product-categories`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ product_categories }) => {
@@ -100,9 +107,9 @@ For example:
export const paginateHighlights = [
["20", "offset", "Calculate the number of product categories to skip based on the current page and limit."],
["28", "searchParams.toString()", "Pass the pagination parameters in the query."],
["33", "count", "The total number of product categories in the Medusa application."],
["45", "setHasMorePages", "Set whether there are more pages based on the total count."],
["64", "button", "Show a button to load more product categories if there are more pages."]
["36", "count", "The total number of product categories in the Medusa application."],
["48", "setHasMorePages", "Set whether there are more pages based on the total count."],
["67", "button", "Show a button to load more product categories if there are more pages."]
]
```tsx highlights={paginateHighlights}
@@ -136,6 +143,9 @@ export default function Categories() {
searchParams.toString()
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ product_categories, count }) => {
@@ -203,6 +213,9 @@ fetch(`http://localhost:9000/store/product-categories?${
searchParams.toString()
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ product_categories, count }) => {
@@ -28,6 +28,9 @@ export const fetchHighlights = [
searchParams.toString()
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ product_category }) => {
@@ -43,8 +46,8 @@ export const highlights = [
["12", "{ params: { id } }: Params", "This is based on Next.js which passes the path parameters as a prop."],
["24", `"*category_children"`, "Select the `category_children` relation."],
["27"], ["28"], ["29"],
["30"], ["31"], ["32"], ["33"], ["34"], ["35"], ["36"],
["50", "", "Show the nested categories."],
["30"], ["31"], ["32"], ["33"], ["34"], ["35"], ["36"], ["37"], ["38"], ["39"],
["53", "", "Show the nested categories."],
]
```tsx highlights={highlights}
@@ -78,6 +81,9 @@ export const highlights = [
searchParams.toString()
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ product_category }) => {
@@ -13,7 +13,7 @@ To retrieve a category's products in the storefront, send a request to the [List
export const fetchHighlights = [
["3", "", "Pass the category ID as a query parameter."],
["9", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["9", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
]
```ts highlights={fetchHighlights}
@@ -25,7 +25,7 @@ export const fetchHighlights = [
fetch(`http://localhost:9000/store/products?${searchParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -42,7 +42,7 @@ export const highlights = [
["13", "params: { categoryId }", "This is based on Next.js which passes the path parameters as a prop."],
["33", "", "Pass the category ID as a query parameter."],
["36"], ["37"], ["38"],
["39", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["39", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["40"], ["41"], ["42"], ["43"], ["44"], ["45"], ["46"], ["47"], ["48"], ["49"], ["50"], ["51"], ["52"], ["53"], ["54"],
["55"], ["56"]
]
@@ -86,7 +86,7 @@ export const highlights = [
fetch(`http://localhost:9000/store/products?${searchParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -27,6 +27,9 @@ export const fetchHighlights = [
```ts highlights={fetchHighlights}
fetch(`http://localhost:9000/store/product-categories/${id}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ product_category }) => {
@@ -41,7 +44,7 @@ export const fetchHighlights = [
export const highlights = [
["12", "{ params: { id } }: Params", "This is based on Next.js which passes the path parameters as a prop."],
["23"], ["24"], ["25"], ["26"],
["27"], ["28"], ["29"], ["30"]
["27"], ["28"], ["29"], ["30"], ["31"], ["32"], ["33"]
]
```tsx highlights={highlights}
@@ -69,6 +72,9 @@ export const highlights = [
fetch(`http://localhost:9000/store/product-categories/${id}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ product_category }) => {
@@ -114,6 +120,9 @@ export const handleFetchHighlights = [
handle
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ product_categories }) => {
@@ -133,7 +142,7 @@ export const handleHighlights = [
["12", "{ params: { handle } }: Params", "This is based on Next.js which passes the path parameters as a prop."],
["23"], ["24"], ["25"], ["26"],
["27"], ["28"], ["29"], ["30"],
["31"], ["32"], ["33"], ["34"]
["31"], ["32"], ["33"], ["34"], ["35"], ["36"], ["37"]
]
```tsx highlights={handleHighlights}
@@ -163,6 +172,9 @@ export const handleHighlights = [
handle
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ product_categories }) => {
@@ -18,6 +18,9 @@ To retrieve the list of product collections, send a request to the [List Product
```ts
fetch(`http://localhost:9000/store/collections`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ collections }) => {
@@ -31,7 +34,8 @@ To retrieve the list of product collections, send a request to the [List Product
export const highlights = [
["17"], ["18"], ["19"], ["20"],
["21"], ["22"], ["23"], ["24"]
["21"], ["22"], ["23"], ["24"],
["25"], ["26"], ["27"]
]
```tsx highlights={highlights}
@@ -53,6 +57,9 @@ export const highlights = [
fetch(`http://localhost:9000/store/collections`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ collections: dataCollections }) => {
@@ -102,9 +109,9 @@ For example:
export const paginateHighlights = [
["20", "offset", "Calculate the number of product collections to skip based on the current page and limit."],
["28", "searchParams.toString()", "Pass the pagination parameters in the query."],
["33", "count", "The total number of product collections in the Medusa application."],
["45", "setHasMorePages", "Set whether there are more pages based on the total count."],
["64", "button", "Show a button to load more product collections if there are more pages."]
["36", "count", "The total number of product collections in the Medusa application."],
["48", "setHasMorePages", "Set whether there are more pages based on the total count."],
["67", "button", "Show a button to load more product collections if there are more pages."]
]
```tsx highlights={paginateHighlights}
@@ -138,6 +145,9 @@ export default function Collections() {
searchParams.toString()
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ collections: dataCollections, count }) => {
@@ -205,6 +215,9 @@ fetch(`http://localhost:9000/store/collections?${
searchParams.toString()
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ collections, count }) => {
@@ -13,7 +13,7 @@ To retrieve a collection's products in the storefront, send a request to the [Li
export const fetchHighlights = [
["3", "", "Pass the collection ID as a query parameter."],
["9", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["9", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
]
```ts highlights={fetchHighlights}
@@ -25,7 +25,7 @@ export const fetchHighlights = [
fetch(`http://localhost:9000/store/products?${searchParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -42,7 +42,7 @@ export const highlights = [
["13", "params: { collectionId }", "This is based on Next.js which passes the path parameters as a prop."],
["33", "", "Pass the collection ID as a query parameter."],
["36"], ["37"], ["38"],
["39", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["39", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["40"], ["41"], ["42"], ["43"], ["44"], ["45"], ["46"], ["47"], ["48"], ["49"], ["50"], ["51"], ["52"], ["53"], ["54"],
["55"], ["56"], ["57"], ["58"]
]
@@ -88,7 +88,7 @@ export const highlights = [
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -27,6 +27,9 @@ export const fetchHighlights = [
```ts highlights={fetchHighlights}
fetch(`http://localhost:9000/store/collections/${id}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ collection }) => {
@@ -41,7 +44,8 @@ fetch(`http://localhost:9000/store/collections/${id}`, {
export const highlights = [
["12", "{ params: { id } }: Params", "This is based on Next.js which passes the path parameters as a prop."],
["23"], ["24"], ["25"], ["26"],
["27"], ["28"], ["29"], ["30"]
["27"], ["28"], ["29"], ["30"],
["31"], ["32"], ["33"]
]
```tsx highlights={highlights}
@@ -69,6 +73,9 @@ export const highlights = [
fetch(`http://localhost:9000/store/collections/${id}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ collection: dataCollection }) => {
@@ -115,6 +122,9 @@ export const handleFetchHighlights = [
handle
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ collections }) => {
@@ -133,7 +143,8 @@ export const handleFetchHighlights = [
export const handleHighlights = [
["13", "{ params: { handle } }: Params", "This is based on Next.js which passes the path parameters as a prop."],
["25"], ["26"], ["27"], ["28"],
["29"], ["30"], ["31"], ["32"], ["33"], ["34"], ["35"], ["36"]
["29"], ["30"], ["31"], ["32"], ["33"], ["34"], ["35"], ["36"],
["37"], ["38"], ["39"]
]
```tsx highlights={handleHighlights}
@@ -165,6 +176,9 @@ export const handleHighlights = [
handle
}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ collections }) => {
@@ -15,7 +15,7 @@ For example:
export const fetchHighlights = [
["2", "fields", "Pass `+variants.inventory_quantity` in the fields to retrieve."],
["8", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve the inventory quantity based on the associated sales channels' stock locations."],
["8", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve the inventory quantity based on the associated sales channels' stock locations."],
["14", "isInStock", "Consider the variant in stock either if its `manage_inventory` property is disabled, or the `inventory_quantity` is greater than `0`."]
]
@@ -27,7 +27,7 @@ const queryParams = new URLSearchParams({
fetch(`http://localhost:9000/store/products/${id}?${queryParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -61,7 +61,7 @@ A variant is in stock if:
export const reactHighlights = [
["12", "{ params: { id } }: Params", "This is based on Next.js which passes the path parameters as a prop."],
["25", "fields", "Pass `+variants.inventory_quantity` in the fields to retrieve."],
["31", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve the inventory quantity based on the associated sales channels' stock locations."],
["31", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve the inventory quantity based on the associated sales channels' stock locations."],
["55", "isInStock", "Consider the selected variant in stock either if its `manage_inventory` property is disabled, or the `inventory_quantity` is greater than `0`."],
["96", "isInStock", "Show whether the selected variant is in stock."]
]
@@ -97,7 +97,7 @@ export default function Product({ params: { id } }: Params) {
fetch(`http://localhost:9000/store/products/${id}?${queryParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -16,14 +16,14 @@ To list products, send a request to the [List Products API route](!api!/store#pr
<CodeTab label="Fetch API" value="fetch">
export const fetchHighlights = [
["4", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["4", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
]
```ts highlights={fetchHighlights}
fetch(`http://localhost:9000/store/products`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -38,7 +38,7 @@ export const fetchHighlights = [
export const highlights = [
["17"], ["18"], ["19"],
["20", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["20", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["21"], ["22"], ["23"], ["24"], ["25"], ["26"], ["27"]
]
@@ -62,7 +62,7 @@ export const highlights = [
fetch(`http://localhost:9000/store/products`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -146,7 +146,7 @@ export default function Products() {
fetch(`http://localhost:9000/store/products?${searchParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -212,7 +212,7 @@ const searchParams = new URLSearchParams({
fetch(`http://localhost:9000/store/products?${searchParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -99,7 +99,7 @@ export default function Product({ params: { id } }: Params) {
fetch(`http://localhost:9000/store/products/${id}?${queryParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -100,7 +100,7 @@ export default function Product({ params: { id } }: Params) {
fetch(`http://localhost:9000/store/products/${id}?${queryParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -31,7 +31,7 @@ const queryParams = new URLSearchParams({
fetch(`http://localhost:9000/store/products/${id}?${queryParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -141,7 +141,7 @@ export default function Product({ params: { id } }: Params) {
fetch(`http://localhost:9000/store/products/${id}?${queryParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -30,7 +30,7 @@ const queryParams = new URLSearchParams({
fetch(`http://localhost:9000/store/products/${id}?${queryParams.toString()}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -22,14 +22,14 @@ To retrieve a product by its ID, send a request to the [Retrieve Product API rou
export const fetchHighlights = [
["1", "id", "The product's ID."],
["4", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["4", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
]
```ts highlights={fetchHighlights}
fetch(`http://localhost:9000/store/products/${id}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -45,7 +45,7 @@ export const fetchHighlights = [
export const highlights = [
["12", "{ params: { id } }: Params", "This is based on Next.js which passes the path parameters as a prop."]
["23"], ["24"], ["25"],
["26", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["26", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["27"], ["28"], ["29"], ["30"], ["31"], ["32"], ["33"]
]
@@ -75,7 +75,7 @@ export const highlights = [
fetch(`http://localhost:9000/store/products/${id}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -133,14 +133,14 @@ To retrieve a product by its handle, send a request to the [List Products API ro
export const handleFetchHighlights = [
["1", "id", "The product's ID."],
["4", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["4", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
]
```ts highlights={handleFetchHighlights}
fetch(`http://localhost:9000/store/products?handle=${handle}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -160,7 +160,7 @@ export const handleFetchHighlights = [
export const handleHighlights = [
["12", "{ params: { handle } }: Params", "This is based on Next.js which passes the path parameters as a prop."]
["23"], ["24"], ["25"],
["26", "process.env.NEXT_PUBLIC_PAK", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["26", "process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "Pass the Publishable API key to retrieve products of associated sales channel(s)."],
["27"], ["28"], ["29"], ["30"], ["31"], ["32"], ["33"], ["34"], ["35"]
]
@@ -190,7 +190,7 @@ export const handleHighlights = [
fetch(`http://localhost:9000/store/products?handle=${handle}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -55,7 +55,7 @@ export default function Product({ params: { id } }: Params) {
fetch(`http://localhost:9000/store/products/${id}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
@@ -0,0 +1,80 @@
export const metadata = {
title: `Use a Publishable API Key in the Storefront`,
}
# {metadata.title}
When sending requests to the `/store` API routes, you must pass the publishable API key in the header of your request.
## What is a Publishable API Key?
Publishable API keys specify the scope of a request. Admin users create them, and they can only be used on the client-side, such as in a storefront.
Publishable API keys are associated with sales channels. Then, when the publishable API key is passed in the header of a request, the Medusa application automatically infers what sales channel is being used.
---
## How to Create a Publishable API Key?
{/* TODO replace link with admin how-to guide once available. */}
You create a publishable API key either using the Medusa Admin or the [Admin API routes](!api!/admin#api-keys_postapikeys).
For example, using the [Create API Key API Route](!api!/admin#api-keys_postapikeys):
```bash
curl -X POST 'http://localhost:9000/admin/api-keys' \
-H 'Authorization: Bearer {token}' \
-H 'Content-Type: application/json' \
--data-raw '{
"title": "Storefront Key",
"type": "publishable"
}'
```
<Note title="Tip">
Learn how to send authenticated admin requests in the [Admin API reference](!api!/admin#authentication)
</Note>
To add sales channels to the publishable API key's scope, use the [Manage Sales Channels API route](!api!/admin#api-keys_postapikeysidsaleschannels):
```bash
curl -X POST 'http://localhost:9000/admin/api-keys/apk_123/sales-channels' \
-H 'Authorization: Bearer {token}' \
-H 'Content-Type: application/json' \
--data-raw '{
"add": ["sc_123"]
}'
```
Make sure to replace `apk_123` with the ID of the publishable API key, and `sc_123` with the ID of the sales channel.
---
## How to Use Publishable API Key in Storefront Requests
In your storefront, pass the `x-publishable-api-key` in the header of all your requests to the Medusa application.
For example:
export const highlights = [
["4", "NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY", "An environment variable that holds the publishable API key's token."]
]
```ts
fetch(`http://localhost:9000/store/products`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then((data) => {
// use products...
console.log(data.products)
})
```
Where `NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY` is an environment variable that holds your publishable API key's token.
@@ -21,8 +21,8 @@ export const highlights = [
["32", "", "If a region is set, set its ID in the local storage again in case it changed."],
["39", "regionId", "Retrieve the selected region from the `localStorage`."],
["42", "fetch", "If no region is selected, retrieve the list of regions from the Medusa application and select the first one."],
["51", "fetch", "If a region is selected, retrieve it from the Medusa application."],
["71", "useRegion", "The hook that child components of the provider use to access the region."]
["54", "fetch", "If a region is selected, retrieve it from the Medusa application."],
["77", "useRegion", "The hook that child components of the provider use to access the region."]
]
```tsx highlights={highlights}
@@ -69,6 +69,9 @@ export const RegionProvider = (
// retrieve regions and select the first one
fetch(`http://localhost:9000/store/regions`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ regions }) => {
@@ -78,6 +81,9 @@ export const RegionProvider = (
// retrieve selected region
fetch(`http://localhost:9000/store/regions/${regionId}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ region: dataRegion }) => {
@@ -14,6 +14,9 @@ To list regions in your storefront, send a request to the [List Regions API rout
```ts
fetch(`http://localhost:9000/store/regions`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ regions }) => {
@@ -26,7 +29,8 @@ To list regions in your storefront, send a request to the [List Regions API rout
<CodeTab label="React" value="react">
export const highlights = [
["17"], ["18"], ["19"], ["20"], ["21"], ["22"], ["23"], ["24"]
["17"], ["18"], ["19"], ["20"], ["21"], ["22"], ["23"], ["24"],
["25"], ["26"], ["27"]
]
```tsx highlights={highlights}
@@ -48,6 +52,9 @@ export const highlights = [
fetch(`http://localhost:9000/store/regions`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ regions: dataRegions }) => {
@@ -33,6 +33,9 @@ const regionId = localStorage.getItem("region_id")
fetch(`http://localhost:9000/store/regions/${regionId}`, {
credentials: "include",
headers: {
"x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
},
})
.then((res) => res.json())
.then(({ region }) => {
@@ -51,21 +51,3 @@ module.exports = defineConfig({
// ...
})
```
---
## Use Publishable API Keys
Publishable API keys specify the scope of a request. Admin users create them, and they can only be used on the client-side, such as in a storefront.
Publishable API keys are associated with sales channels. Then, when the publishable API key is passed in the header of a request, the Medusa application automatically infers what sales channel is being used.
<Note>
Products, carts, and orders are associated with a sales channel. If you don’t specify a sales channel or a publishable API key, the products, carts, and orders are associated with the default sales channel.
</Note>
{/* TODO replace link with admin how-to guide once available. */}
Create a publishable API key either using the Medusa Admin or the [Admin API routes](!api!/admin#api-keys_postapikeys).