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:
1 parent
ef8dc4087e
commit
58f06be44d
66 files changed
+577
-298
No files matched your search
@@ -140,34 +140,31 @@ fetch(`<BACKEND_URL>/store/products`, {
|
||||
|
||||
## Publishable API Key
|
||||
|
||||
Publishable API Keys allow you to send a request with a pre-defined scope. You can associate the
|
||||
publishable API key with one or more resources, such as sales channels, then include the publishable
|
||||
API key in the header of your requests.
|
||||
You must pass a publishable API key in the header of your requests to the store API routes.
|
||||
|
||||
The Medusa application will infer the scope of the current
|
||||
request based on the publishable API key. At the moment, publishable API keys only work with sales channels.
|
||||
|
||||
It's highly recommended to create a publishable API key and pass it in the header of all your requests to the
|
||||
store APIs.
|
||||
|
||||
{/* TODO add link to the v2 guide */}
|
||||
|
||||
{/* You can learn more about publishable API keys and how to use them in [this documentation](https://docs.medusajs.com/development/publishable-api-keys/). */}
|
||||
Publishable API Keys sets the scope of your request to one or more sales channels. This ensures you only
|
||||
retrieve products available in the publishable API key's sales channels, retrieve correct inventory details,
|
||||
and associate placed orders with the specified sales channel.
|
||||
|
||||
### How to Create a Publishable API Key
|
||||
|
||||
{/* TODO add v2 links */}
|
||||
|
||||
Create a publishable API key either using the admin REST APIs, or using the Medusa Admin.
|
||||
Create a publishable API key either using the [admin REST APIs](https://docs.medusajs.com/v2/api/admin#api-keys_postapikeys), or using the Medusa Admin.
|
||||
|
||||
### How to Use a Publishable API Key
|
||||
|
||||
You can pass the publishable API key in the header `x-publishable-api-key` in all your requests to the store APIs:
|
||||
You pass the publishable API key in the header `x-publishable-api-key` in all your requests to the store APIs.
|
||||
|
||||
For example:
|
||||
|
||||
```bash
|
||||
x-publishable-api-key: {your_publishable_api_key}
|
||||
curl 'http://localhost:9000/store/products' \
|
||||
-H 'x-publishable-api-key: {your_publishable_api_key}'
|
||||
```
|
||||
|
||||
Where `{your_publishable_api_key}` is the token of the publishable API key.
|
||||
|
||||
<Feedback
|
||||
event="survey_api-ref"
|
||||
extraData={{
|
||||
|
||||
@@ -12,9 +12,9 @@ An API route is created for every HTTP method you export a handler function for
|
||||
|
||||
Allowed HTTP methods are: `GET`, `POST`, `DELETE`, `PUT`, `PATCH`, `OPTIONS`, and `HEAD`.
|
||||
|
||||
For example, create the file `src/api/store/hello-world/route.ts` with the following content:
|
||||
For example, create the file `src/api/hello-world/route.ts` with the following content:
|
||||
|
||||
```ts title="src/api/store/hello-world/route.ts"
|
||||
```ts title="src/api/hello-world/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -41,5 +41,5 @@ export const POST = async (
|
||||
|
||||
This adds two API Routes:
|
||||
|
||||
- A `GET` route at `http://localhost:9000/store/hello-world`.
|
||||
- A `POST` route at `http://localhost:9000/store/hello-world`.
|
||||
- A `GET` route at `http://localhost:9000/hello-world`.
|
||||
- A `POST` route at `http://localhost:9000/hello-world`.
|
||||
@@ -37,7 +37,7 @@ import type {
|
||||
export default defineMiddlewares({
|
||||
routes: [
|
||||
{
|
||||
matcher: "/store*",
|
||||
matcher: "/custom*",
|
||||
middlewares: [
|
||||
(
|
||||
req: MedusaRequest,
|
||||
@@ -59,7 +59,7 @@ The `defineMiddlewares` function accepts a middleware configurations object that
|
||||
- `matcher`: a string or regular expression indicating the API route path to apply the middleware on. The regular expression must be compatible with [path-to-regexp](https://github.com/pillarjs/path-to-regexp).
|
||||
- `middlewares`: An array of middleware functions.
|
||||
|
||||
In the example above, you define a middleware that logs the message `Received a request!` whenever a request is sent to an API route path starting with `/store`.
|
||||
In the example above, you define a middleware that logs the message `Received a request!` whenever a request is sent to an API route path starting with `/custom`.
|
||||
|
||||
---
|
||||
|
||||
@@ -73,7 +73,7 @@ To test the middleware:
|
||||
npm run dev
|
||||
```
|
||||
|
||||
2. Send a request to any API route starting with `/store`.
|
||||
2. Send a request to any API route starting with `/custom`.
|
||||
3. See the following message in the terminal:
|
||||
|
||||
```bash
|
||||
@@ -128,7 +128,7 @@ import type {
|
||||
export default defineMiddlewares({
|
||||
routes: [
|
||||
{
|
||||
matcher: "/store/custom/:id",
|
||||
matcher: "/custom/:id",
|
||||
middlewares: [
|
||||
// ...
|
||||
],
|
||||
@@ -137,7 +137,7 @@ export default defineMiddlewares({
|
||||
})
|
||||
```
|
||||
|
||||
This applies a middleware to the routes defined in the file `src/api/store/custom/[id]/route.ts`.
|
||||
This applies a middleware to the routes defined in the file `src/api/custom/[id]/route.ts`.
|
||||
|
||||
---
|
||||
|
||||
@@ -160,7 +160,7 @@ import type {
|
||||
export default defineMiddlewares({
|
||||
routes: [
|
||||
{
|
||||
matcher: "/store*",
|
||||
matcher: "/custom*",
|
||||
method: ["POST", "PUT"],
|
||||
middlewares: [
|
||||
// ...
|
||||
@@ -172,7 +172,7 @@ export default defineMiddlewares({
|
||||
|
||||
`method`'s value is one or more HTTP methods to apply the middleware to.
|
||||
|
||||
This example applies the middleware only when a `POST` or `PUT` request is sent to an API route path starting with `/store`.
|
||||
This example applies the middleware only when a `POST` or `PUT` request is sent to an API route path starting with `/custom`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@ In this chapter, you’ll learn about path, query, and request body parameters.
|
||||
|
||||
To create an API route that accepts a path parameter, create a directory within the route file's path whose name is of the format `[param]`.
|
||||
|
||||
For example, to create an API Route at the path `/hello-world/:id`, where `:id` is a path parameter, create the file `src/api/store/hello-world/[id]/route.ts` with the following content:
|
||||
For example, to create an API Route at the path `/hello-world/:id`, where `:id` is a path parameter, create the file `src/api/hello-world/[id]/route.ts` with the following content:
|
||||
|
||||
export const singlePathHighlights = [
|
||||
["11", "req.params.id", "Access the path parameter `id`"]
|
||||
]
|
||||
|
||||
```ts title="src/api/store/hello-world/[id]/route.ts" highlights={singlePathHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world/{id}" testApiMethod="GET" testPathParams={{ "id": "" }}
|
||||
```ts title="src/api/hello-world/[id]/route.ts" highlights={singlePathHighlights}
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -38,14 +38,14 @@ The `MedusaRequest` object has a `params` property. `params` holds the path para
|
||||
|
||||
To create an API route that accepts multiple path parameters, create within the file's path multiple directories whose names are of the format `[param]`.
|
||||
|
||||
For example, to create an API route at `/store/hello-world/:id/name/:name`, create the file `src/api/store/hello-world/[id]/name/[name]/route.ts` with the following content:
|
||||
For example, to create an API route at `/hello-world/:id/name/:name`, create the file `src/api/hello-world/[id]/name/[name]/route.ts` with the following content:
|
||||
|
||||
export const multiplePathHighlights = [
|
||||
["12", "req.params.id", "Access the path parameter `id`"],
|
||||
["13", "req.params.name", "Access the path parameter `name`"]
|
||||
]
|
||||
|
||||
```ts title="src/api/store/hello-world/[id]/name/[name]/route.ts" highlights={multiplePathHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world/{id}/name/{name}" testApiMethod="GET" testPathParams={{ "id": "", "name": "" }}
|
||||
```ts title="src/api/hello-world/[id]/name/[name]/route.ts" highlights={multiplePathHighlights}
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -77,7 +77,7 @@ export const queryHighlights = [
|
||||
["11", "req.query.name", "Access the query parameter `name`"],
|
||||
]
|
||||
|
||||
```ts title="src/api/store/hello-world/route.ts" highlights={queryHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world" testApiMethod="GET" testQueryParams={{ "name": "" }}
|
||||
```ts title="src/api/hello-world/route.ts" highlights={queryHighlights}
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -108,7 +108,7 @@ export const bodyHighlights = [
|
||||
["15", "req.body.name", "Access the request body parameter `name`"],
|
||||
]
|
||||
|
||||
```ts title="src/api/store/hello-world/route.ts" highlights={bodyHighlights}
|
||||
```ts title="src/api/hello-world/route.ts" highlights={bodyHighlights}
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -138,8 +138,8 @@ The `MedusaRequest` type accepts a type argument that indicates the type of the
|
||||
|
||||
To test it out, send the following request to your Medusa application:
|
||||
|
||||
```bash apiTesting testApiUrl="http://localhost:9000/store/hello-world" testApiMethod="POST" testBodyParams={{ "name": "" }}
|
||||
curl -X POST 'http://localhost:9000/store/hello-world' \
|
||||
```bash
|
||||
curl -X POST 'http://localhost:9000/hello-world' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"name": "John"
|
||||
|
||||
@@ -20,7 +20,7 @@ Requests to `/admin` must be user-authenticated to access the route.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Refer to the API Reference for [Admin](https://docs.medusajs.com/api/admin#authentication) and [Store](https://docs.medusajs.com/api/store#authentication) authentication methods.
|
||||
Refer to the API Reference for [Admin](!api!/admin#authentication) and [Store](!api!/store#authentication) authentication methods.
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ export const jsonHighlights = [
|
||||
["7", "json", "Return a JSON object."]
|
||||
]
|
||||
|
||||
```ts title="src/api/store/custom/route.ts" highlights={jsonHighlights} apiTesting testApiUrl="http://localhost:9000/store/custom" testApiMethod="GET"
|
||||
```ts title="src/api/custom/route.ts" highlights={jsonHighlights}
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
|
||||
|
||||
export const GET = async (
|
||||
@@ -51,7 +51,7 @@ export const statusHighlight = [
|
||||
["7", "status", "Set the response code to `201`."]
|
||||
]
|
||||
|
||||
```ts title="src/api/store/custom/route.ts" highlights={statusHighlight} apiTesting testApiUrl="http://localhost:9000/store/custom" testApiMethod="GET"
|
||||
```ts title="src/api/custom/route.ts" highlights={statusHighlight}
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
|
||||
|
||||
export const GET = async (
|
||||
|
||||
@@ -8,7 +8,7 @@ In this chapter, you'll learn how to validate request body parameters in your cu
|
||||
|
||||
## Example Scenario
|
||||
|
||||
Consider you're creating a `POST` API route at `/store/custom`. It accepts two paramters `a` and `b` that are required numbers, and returns their sum.
|
||||
Consider you're creating a `POST` API route at `/custom`. It accepts two paramters `a` and `b` that are required numbers, and returns their sum.
|
||||
|
||||
The next steps explain how to add validation to this API route, as an example.
|
||||
|
||||
@@ -20,9 +20,9 @@ Medusa uses [Zod](https://zod.dev/) to validate the body parameters of an incomi
|
||||
|
||||
To use Zod to validate your custom schemas, create a `validators.ts` file in any `src/api` subfolder. This file holds Zod schemas for each of your API routes.
|
||||
|
||||
For example, create the file `src/api/store/custom/validators.ts` with the following content:
|
||||
For example, create the file `src/api/custom/validators.ts` with the following content:
|
||||
|
||||
```ts title="src/api/store/custom/validators.ts"
|
||||
```ts title="src/api/custom/validators.ts"
|
||||
import { z } from "zod"
|
||||
|
||||
export const PostStoreCustomSchema = z.object({
|
||||
@@ -41,7 +41,7 @@ The `PostStoreCustomSchema` variable is a Zod schema that indicates the request
|
||||
|
||||
## Step 2: Add Validation Middleware
|
||||
|
||||
To use this schema for validating the body parameters of requests to `/store/custom`, use the `validateAndTransformBody` middleware provided by `@medusajs/medusa`. It accepts the Zod schema as a parameter.
|
||||
To use this schema for validating the body parameters of requests to `/custom`, use the `validateAndTransformBody` middleware provided by `@medusajs/medusa`. It accepts the Zod schema as a parameter.
|
||||
|
||||
For example, create the file `src/api/middlewares.ts` with the following content:
|
||||
|
||||
@@ -50,12 +50,12 @@ import { defineMiddlewares } from "@medusajs/medusa"
|
||||
import {
|
||||
validateAndTransformBody,
|
||||
} from "@medusajs/medusa/dist/api/utils/validate-body"
|
||||
import { PostStoreCustomSchema } from "./store/custom/validators"
|
||||
import { PostStoreCustomSchema } from "./custom/validators"
|
||||
|
||||
export default defineMiddlewares({
|
||||
routes: [
|
||||
{
|
||||
matcher: "/store/custom",
|
||||
matcher: "/custom",
|
||||
method: "POST",
|
||||
middlewares: [
|
||||
validateAndTransformBody(PostStoreCustomSchema),
|
||||
@@ -65,7 +65,7 @@ export default defineMiddlewares({
|
||||
})
|
||||
```
|
||||
|
||||
This applies the `validateAndTransformBody` middleware on `POST` requests to `/store/custom`. It uses the `PostStoreCustomSchema` as the validation schema.
|
||||
This applies the `validateAndTransformBody` middleware on `POST` requests to `/custom`. It uses the `PostStoreCustomSchema` as the validation schema.
|
||||
|
||||
### How the Validation Works
|
||||
|
||||
@@ -79,14 +79,14 @@ If a request's body parameters are validated successfully, the middleware sets t
|
||||
|
||||
In your API route, consume the validated body using the `validatedBody` property of `MedusaRequest`.
|
||||
|
||||
For example, create the file `src/api/store/custom/route.ts` with the following content:
|
||||
For example, create the file `src/api/custom/route.ts` with the following content:
|
||||
|
||||
export const routeHighlights = [
|
||||
["5", "PostStoreCustomSchemaType", "Infer the request body type from the schema to pass it as a type parameter to `MedusaRequest`."],
|
||||
["14", "", "Access the body parameters using `validatedBody`."]
|
||||
]
|
||||
|
||||
```ts title="src/api/store/custom/route.ts" highlights={routeHighlights}
|
||||
```ts title="src/api/custom/route.ts" highlights={routeHighlights}
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
|
||||
import { z } from "zod"
|
||||
import { PostStoreCustomSchema } from "./validators"
|
||||
@@ -117,7 +117,7 @@ To pass the request body's type as a type parameter to `MedusaRequest`, use Zod'
|
||||
|
||||
## Test it Out
|
||||
|
||||
To test out the validation, send a `POST` request to `/store/custom`. You can try sending incorrect request body parameters.
|
||||
To test out the validation, send a `POST` request to `/custom`. You can try sending incorrect request body parameters.
|
||||
|
||||
For example, if you omit the `a` parameter, you'll receive a `400` response code with the following response data:
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ In your resources, such as API routes or workflows, you can resolve Query to fet
|
||||
|
||||
## Query Example
|
||||
|
||||
For example, create the route `src/api/store/query/route.ts` with the following content:
|
||||
For example, create the route `src/api/query/route.ts` with the following content:
|
||||
|
||||
export const exampleHighlights = [
|
||||
["13", "", "Resolve Query from the Medusa container."],
|
||||
@@ -33,7 +33,7 @@ export const exampleHighlights = [
|
||||
["17", "fields", "An array of the data model’s properties to retrieve in the result."],
|
||||
]
|
||||
|
||||
```ts title="src/api/store/query/route.ts" highlights={exampleHighlights} apiTesting testApiMethod="GET" testApiUrl="http://localhost:9000/store/query" collapsibleLines="1-8" expandButtonLabel="Show Imports"
|
||||
```ts title="src/api/query/route.ts" highlights={exampleHighlights} collapsibleLines="1-8" expandButtonLabel="Show Imports"
|
||||
import {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
|
||||
@@ -19,7 +19,7 @@ export const highlights = [
|
||||
["14", "throwOnError", "Specify that errors occuring during the workflow's execution should be returned, not thrown."],
|
||||
]
|
||||
|
||||
```ts title="src/api/store/workflows/route.ts" highlights={highlights} collapsibleLines="1-6" expandButtonLabel="Show Imports"
|
||||
```ts title="src/api/workflows/route.ts" highlights={highlights} collapsibleLines="1-6" expandButtonLabel="Show Imports"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
|
||||
@@ -239,9 +239,9 @@ In the workflow construction function, you first run the `updateProduct` step, t
|
||||
|
||||
You can now use and execute your workflow in your Medusa application.
|
||||
|
||||
To execute the workflow in an API route, create the file `src/api/store/products/[id]/erp/route.ts` with the following content:
|
||||
To execute the workflow in an API route, create the file `src/api/products/[id]/erp/route.ts` with the following content:
|
||||
|
||||
```ts title="src/api/store/products/[id]/erp/route.ts"
|
||||
```ts title="src/api/products/[id]/erp/route.ts"
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
|
||||
import updateProductAndErpWorkflow, {
|
||||
UpdateProductAndErpWorkflowInput,
|
||||
|
||||
@@ -79,7 +79,7 @@ export default myWorkflow
|
||||
|
||||
3. Execute the workflow from a resource, such as an API route:
|
||||
|
||||
```ts title="src/api/store/workflow/route.ts" collapsibleLines="1-6" expandButtonLabel="Show Imports"
|
||||
```ts title="src/api/workflow/route.ts" collapsibleLines="1-6" expandButtonLabel="Show Imports"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -103,10 +103,10 @@ export async function GET(
|
||||
npm run dev
|
||||
```
|
||||
|
||||
5. Send a `GET` request to `/store/workflow`:
|
||||
5. Send a `GET` request to `/workflow`:
|
||||
|
||||
```bash apiTesting testApiMethod="GET" testApiUrl="http://localhost:9000/store/workflow"
|
||||
curl http://localhost:9000/store/workflow
|
||||
```bash
|
||||
curl http://localhost:9000/workflow
|
||||
```
|
||||
|
||||
In the console, you'll see:
|
||||
|
||||
@@ -276,7 +276,7 @@ export const highlights = [
|
||||
["30", "subscribe", "Subscribe to status changes of the workflow execution."],
|
||||
]
|
||||
|
||||
```ts title="src/api/store/workflows/route.ts" highlights={highlights} collapsibleLines="1-11" expandButtonLabel="Show Imports"
|
||||
```ts title="src/api/workflows/route.ts" highlights={highlights} collapsibleLines="1-11" expandButtonLabel="Show Imports"
|
||||
import type { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
|
||||
import myWorkflow from "../../../workflows/hello-world"
|
||||
import {
|
||||
|
||||
@@ -20,9 +20,9 @@ An API Route is created in a TypeScript or JavaScript file under the `src/api` d
|
||||
|
||||
Each file exports API Route handler functions for at least one HTTP method (`GET`, `POST`, `DELETE`, etc…).
|
||||
|
||||
For example, to create a `GET` API Route at `/store/hello-world`, create the file `src/api/store/hello-world/route.ts` with the following content:
|
||||
For example, to create a `GET` API Route at `/hello-world`, create the file `src/api/hello-world/route.ts` with the following content:
|
||||
|
||||
```ts title="src/api/store/hello-world/route.ts"
|
||||
```ts title="src/api/hello-world/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -46,10 +46,10 @@ To test the API route above, start the Medusa application:
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Then, send a `GET` request to the `/store/hello-world` API Route:
|
||||
Then, send a `GET` request to the `/hello-world` API Route:
|
||||
|
||||
```bash apiTesting testApiUrl="http://localhost:9000/store/hello-world" testApiMethod="GET"
|
||||
curl http://localhost:9000/store/hello-world
|
||||
```bash
|
||||
curl http://localhost:9000/hello-world
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -105,9 +105,9 @@ Resolving a module's service is essential to use its methods that perform action
|
||||
|
||||
</Note>
|
||||
|
||||
For example, create the API route `src/api/store/custom/route.ts` with the following content:
|
||||
For example, create the API route `src/api/custom/route.ts` with the following content:
|
||||
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
```ts title="src/api/custom/route.ts"
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
|
||||
import HelloModuleService from "../../../modules/hello/service"
|
||||
import { HELLO_MODULE } from "../../../modules/hello"
|
||||
@@ -132,10 +132,10 @@ Then, start the Medusa application:
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Finally, send a `GET` request to `/store/custom`:
|
||||
Finally, send a `GET` request to `/custom`:
|
||||
|
||||
```bash apiTesting testApiUrl="http://localhost:9000/store/custom" testApiMethod="GET"
|
||||
curl http://localhost:9000/store/custom
|
||||
```bash
|
||||
curl http://localhost:9000/custom
|
||||
```
|
||||
|
||||
You’ll receive the following response:
|
||||
|
||||
@@ -96,7 +96,7 @@ To execute the workflow, invoke it passing the Medusa container as a parameter.
|
||||
<CodeTabs group="resource-types">
|
||||
<CodeTab label="API Route" value="api-route">
|
||||
|
||||
```ts title="src/api/store/workflow/route.ts" highlights={[["11"], ["12"], ["13"], ["14"], ["15"], ["16"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports"
|
||||
```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"], ["13"], ["14"], ["15"], ["16"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -193,10 +193,10 @@ To test out your workflow, start your Medusa application:
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Then, send a `GET` request to `/store/workflow`:
|
||||
Then, send a `GET` request to `/workflow`:
|
||||
|
||||
```bash apiTesting testApiMethod="GET" testApiUrl="http://localhost:9000/store/workflow"
|
||||
curl http://localhost:9000/store/workflow
|
||||
```bash
|
||||
curl http://localhost:9000/workflow
|
||||
```
|
||||
|
||||
You’ll receive the following response:
|
||||
|
||||
+21
-21
@@ -19,9 +19,9 @@ In this chapter, you'll learn how to write integration tests for API routes usin
|
||||
|
||||
## Test a GET API Route
|
||||
|
||||
Consider the following API route created at `src/api/store/custom/route.ts`:
|
||||
Consider the following API route created at `src/api/custom/route.ts`:
|
||||
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
```ts title="src/api/custom/route.ts"
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
|
||||
|
||||
export async function GET(
|
||||
@@ -37,7 +37,7 @@ export async function GET(
|
||||
To write an integration test that tests this API route, create the file `integration-tests/http/custom-routes.spec.ts` with the following content:
|
||||
|
||||
export const getHighlights = [
|
||||
["8", "api.get", "Send a GET request to the `/store/custom` API route."]
|
||||
["8", "api.get", "Send a GET request to the `/custom` API route."]
|
||||
]
|
||||
|
||||
```ts title="integration-tests/http/custom-routes.spec.ts" highlights={getHighlights}
|
||||
@@ -46,10 +46,10 @@ import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||
medusaIntegrationTestRunner({
|
||||
testSuite: ({ api, getContainer }) => {
|
||||
describe("Custom endpoints", () => {
|
||||
describe("GET /store/custom", () => {
|
||||
describe("GET /custom", () => {
|
||||
it("returns correct message", async () => {
|
||||
const response = await api.get(
|
||||
`/store/custom`
|
||||
`/custom`
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
@@ -64,7 +64,7 @@ medusaIntegrationTestRunner({
|
||||
|
||||
You use the `medusaIntegrationTestRunner` to write your tests.
|
||||
|
||||
You add a single test that sends a `GET` request to `/store/custom` using the `api.get` method. For the test to pass, the response is expected to:
|
||||
You add a single test that sends a `GET` request to `/custom` using the `api.get` method. For the test to pass, the response is expected to:
|
||||
|
||||
- Have a code status `200`,
|
||||
- Have a `message` property in the returned data.
|
||||
@@ -103,9 +103,9 @@ const MyCustom = model.define("my_custom", {
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
And consider that the file `src/api/store/custom/route.ts` defines another route handler for `POST` requests:
|
||||
And consider that the file `src/api/custom/route.ts` defines another route handler for `POST` requests:
|
||||
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
```ts title="src/api/custom/route.ts"
|
||||
// other imports...
|
||||
import HelloModuleService from "../../../modules/hello/service"
|
||||
|
||||
@@ -134,7 +134,7 @@ This API route creates a new record of `MyCustom`.
|
||||
To write tests for this API route, add the following at the end of the `testSuite` function in `integration-tests/http/custom-routes.spec.ts`:
|
||||
|
||||
export const postHighlights = [
|
||||
["14", "api.post", "Send a POST request to the `/store/custom` API route."]
|
||||
["14", "api.post", "Send a POST request to the `/custom` API route."]
|
||||
]
|
||||
|
||||
```ts title="integration-tests/http/custom-routes.spec.ts" highlights={postHighlights}
|
||||
@@ -146,13 +146,13 @@ medusaIntegrationTestRunner({
|
||||
describe("Custom endpoints", () => {
|
||||
// other tests...
|
||||
|
||||
describe("POST /store/custom", () => {
|
||||
describe("POST /custom", () => {
|
||||
const id = "1"
|
||||
|
||||
it("Creates my custom", async () => {
|
||||
|
||||
const response = await api.post(
|
||||
`/store/custom`,
|
||||
`/custom`,
|
||||
{
|
||||
id,
|
||||
name: "Test",
|
||||
@@ -174,7 +174,7 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
```
|
||||
|
||||
This adds a test for the `POST /store/custom` API route. It uses `api.post` to send the POST request. The `api.post` method accepts as a second parameter the data to pass in the request body.
|
||||
This adds a test for the `POST /custom` API route. It uses `api.post` to send the POST request. The `api.post` method accepts as a second parameter the data to pass in the request body.
|
||||
|
||||
The test passes if the response has:
|
||||
|
||||
@@ -188,7 +188,7 @@ To ensure consistency in the database for the rest of the tests after the above
|
||||
|
||||
Use the `getContainer` function passed as a parameter to the `testSuite` function to resolve a service and use it for setup or teardown purposes
|
||||
|
||||
So, add an `afterAll` hook in the `describe` block for `POST /store/custom`:
|
||||
So, add an `afterAll` hook in the `describe` block for `POST /custom`:
|
||||
|
||||
```ts title="integration-tests/http/custom-routes.spec.ts"
|
||||
// other imports...
|
||||
@@ -199,7 +199,7 @@ medusaIntegrationTestRunner({
|
||||
describe("Custom endpoints", () => {
|
||||
// other tests...
|
||||
|
||||
describe("POST /store/custom", () => {
|
||||
describe("POST /custom", () => {
|
||||
// ...
|
||||
afterAll(() => async () => {
|
||||
const helloModuleService: HelloModuleService = getContainer().resolve(
|
||||
@@ -220,9 +220,9 @@ The `afterAll` hook resolves the `HelloModuleService` and use its `deleteMyCusto
|
||||
|
||||
## Test a DELETE API Route
|
||||
|
||||
Consider a `/store/custom/:id` API route created at `src/api/store/custom/[id]/route.ts`:
|
||||
Consider a `/custom/:id` API route created at `src/api/custom/[id]/route.ts`:
|
||||
|
||||
```ts title="src/api/store/custom/[id]/route.ts"
|
||||
```ts title="src/api/custom/[id]/route.ts"
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
|
||||
import HelloModuleService from "../../../modules/hello/service"
|
||||
|
||||
@@ -247,7 +247,7 @@ This API route accepts an ID path parameter, and uses the `HelloModuleService` t
|
||||
To add tests for this API route, add the following to `integration-tests/http/custom-routes.spec.ts`:
|
||||
|
||||
export const deleteHighlights = [
|
||||
["21", "api.delete", "Send a DELETE request to the `/store/custom/:id` API route."]
|
||||
["21", "api.delete", "Send a DELETE request to the `/custom/:id` API route."]
|
||||
]
|
||||
|
||||
```ts title="integration-tests/http/custom-routes.spec.ts" highlights={deleteHighlights}
|
||||
@@ -256,7 +256,7 @@ medusaIntegrationTestRunner({
|
||||
describe("Custom endpoints", () => {
|
||||
// ...
|
||||
|
||||
describe("DELETE /store/custom/:id", () => {
|
||||
describe("DELETE /custom/:id", () => {
|
||||
const id = "1"
|
||||
|
||||
beforeAll(() => async () => {
|
||||
@@ -272,7 +272,7 @@ medusaIntegrationTestRunner({
|
||||
|
||||
it("Deletes my custom", async () => {
|
||||
const response = await api.delete(
|
||||
`/store/custom/${id}`
|
||||
`/custom/${id}`
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
@@ -285,9 +285,9 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
```
|
||||
|
||||
This adds a new test for the `DELETE /store/custom/:id` API route. You use the `beforeAll` hook to create a `MyCustom` record using the `HelloModuleService`.
|
||||
This adds a new test for the `DELETE /custom/:id` API route. You use the `beforeAll` hook to create a `MyCustom` record using the `HelloModuleService`.
|
||||
|
||||
In the test, you use the `api.delete` method to send a `DELETE` request to `/store/custom/:id`. The test passes if the response:
|
||||
In the test, you use the `api.delete` method to send a `DELETE` request to `/custom/:id`. The test passes if the response:
|
||||
|
||||
- Has a `200` status code.
|
||||
- Has a `success` property in its data.
|
||||
|
||||
@@ -10,9 +10,9 @@ In this chapter, you’ll build your first customizations with Medusa.
|
||||
|
||||
API Routes expose business logic through REST APIs. You can create custom API routes to expose custom business logic.
|
||||
|
||||
To create an API route, create the file `src/api/store/hello-world/route.ts` with the following content:
|
||||
To create an API route, create the file `src/api/hello-world/route.ts` with the following content:
|
||||
|
||||
```ts title="src/api/store/hello-world/route.ts"
|
||||
```ts title="src/api/hello-world/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -40,10 +40,10 @@ To test out your customizations:
|
||||
npm run dev
|
||||
```
|
||||
|
||||
2. Send a `GET` request to `/store/hello-world`:
|
||||
2. Send a `GET` request to `/hello-world`:
|
||||
|
||||
```bash apiTesting testApiMethod="GET" testApiUrl="http://localhost:9000/store/hello-world"
|
||||
curl http://localhost:9000/store/hello-world
|
||||
```bash
|
||||
curl http://localhost:9000/hello-world
|
||||
```
|
||||
|
||||
In the response, you’ll receive the following object:
|
||||
|
||||
@@ -13,3 +13,15 @@ You're free to choose how to build your storefront. You can start with our Next.
|
||||
To learn how to build a storefront from scratch, check out the [Storefront Development guides](!resources!/storefront-development) in the Learning Resources documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## Passing a Publishable API Key in Storefront Requests
|
||||
|
||||
When sending a request to an API route starting with `/store`, you must include a publishable API key in the header of your request.
|
||||
|
||||
A publishable API key sets the scope of your request to one or more sales channels.
|
||||
|
||||
Then, when you retrieve products, only products of those sales channels are retrieved. This also ensures you retrieve correct inventory data, and associate created orders with the scoped sales channel.
|
||||
|
||||
Learn more about passing the publishable API key in [this storefront development guide](!resources!/storefront-development/publishable-api-keys).
|
||||
@@ -1,30 +1,30 @@
|
||||
export const generatedEditDates = {
|
||||
"app/basics/scheduled-jobs/page.mdx": "2024-08-05T07:24:27+00:00",
|
||||
"app/basics/workflows/page.mdx": "2024-09-03T08:07:16.276Z",
|
||||
"app/basics/workflows/page.mdx": "2024-09-11T10:48:38.853Z",
|
||||
"app/deployment/page.mdx": "2024-08-05T07:24:05+00:00",
|
||||
"app/page.mdx": "2024-09-03T07:09:09.034Z",
|
||||
"app/basics/modules-and-services/page.mdx": "2024-09-04T15:37:27.695Z",
|
||||
"app/basics/modules-and-services/page.mdx": "2024-09-11T10:48:35.195Z",
|
||||
"app/basics/commerce-modules/page.mdx": "2024-09-03T07:48:48.148Z",
|
||||
"app/advanced-development/workflows/retry-failed-steps/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
"app/advanced-development/workflows/workflow-hooks/page.mdx": "2024-09-10T11:39:51.168Z",
|
||||
"app/cheatsheet/page.mdx": "2024-07-11T13:53:40+03:00",
|
||||
"app/debugging-and-testing/logging/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/more-resources/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/storefront-development/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/storefront-development/page.mdx": "2024-09-11T10:58:59.290Z",
|
||||
"app/storefront-development/nextjs-starter/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/basics/page.mdx": "2024-09-03T07:11:06.879Z",
|
||||
"app/basics/admin-customizations/page.mdx": "2024-09-03T08:07:35.584Z",
|
||||
"app/advanced-development/workflows/workflow-timeout/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
"app/advanced-development/workflows/parallel-steps/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
"app/advanced-development/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/first-customizations/page.mdx": "2024-05-07T18:00:28+02:00",
|
||||
"app/first-customizations/page.mdx": "2024-09-11T10:48:42.374Z",
|
||||
"app/debugging-and-testing/page.mdx": "2024-05-03T17:36:38+03:00",
|
||||
"app/basics/medusa-container/page.mdx": "2024-09-03T07:31:40.214Z",
|
||||
"app/architectural-modules/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/basics/project-directories-files/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/basics/api-routes/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/basics/api-routes/page.mdx": "2024-09-11T10:48:31.777Z",
|
||||
"app/basics/modules-directory-structure/page.mdx": "2024-05-07T18:00:28+02:00",
|
||||
"app/advanced-development/workflows/access-workflow-errors/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/advanced-development/workflows/access-workflow-errors/page.mdx": "2024-09-11T10:46:54.913Z",
|
||||
"app/basics/events-and-subscribers/page.mdx": "2024-09-03T08:01:30.986Z",
|
||||
"app/advanced-development/modules/container/page.mdx": "2024-08-05T07:23:49+00:00",
|
||||
"app/basics/data-models/page.mdx": "2024-09-03T07:58:42.761Z",
|
||||
@@ -33,11 +33,11 @@ export const generatedEditDates = {
|
||||
"app/advanced-development/admin/widgets/page.mdx": "2024-08-06T09:44:22+02:00",
|
||||
"app/advanced-development/data-models/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/advanced-development/modules/remote-link/page.mdx": "2024-07-24T09:16:01+02:00",
|
||||
"app/advanced-development/api-routes/protected-routes/page.mdx": "2024-09-10T11:39:51.166Z",
|
||||
"app/advanced-development/api-routes/protected-routes/page.mdx": "2024-09-11T10:45:44.293Z",
|
||||
"app/advanced-development/workflows/add-workflow-hook/page.mdx": "2024-08-13T09:55:37+03:00",
|
||||
"app/advanced-development/events-and-subscribers/data-payload/page.mdx": "2024-07-16T17:12:05+01:00",
|
||||
"app/advanced-development/data-models/default-properties/page.mdx": "2024-07-02T12:34:44+03:00",
|
||||
"app/advanced-development/workflows/advanced-example/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
"app/advanced-development/workflows/advanced-example/page.mdx": "2024-09-11T10:46:59.975Z",
|
||||
"app/advanced-development/events-and-subscribers/emit-event/page.mdx": "2024-09-10T11:39:51.168Z",
|
||||
"app/advanced-development/workflows/conditions/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
"app/advanced-development/modules/module-link-directions/page.mdx": "2024-07-24T09:16:01+02:00",
|
||||
@@ -55,18 +55,18 @@ export const generatedEditDates = {
|
||||
"app/advanced-development/modules/module-links/page.mdx": "2024-07-24T09:16:01+02:00",
|
||||
"app/advanced-development/data-models/searchable-property/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/advanced-development/scheduled-jobs/execution-number/page.mdx": "2024-07-02T09:41:15+00:00",
|
||||
"app/advanced-development/api-routes/parameters/page.mdx": "2024-09-04T08:17:50.071Z",
|
||||
"app/advanced-development/api-routes/http-methods/page.mdx": "2024-09-04T08:15:11.609Z",
|
||||
"app/advanced-development/api-routes/parameters/page.mdx": "2024-09-11T10:44:13.491Z",
|
||||
"app/advanced-development/api-routes/http-methods/page.mdx": "2024-09-11T10:43:33.169Z",
|
||||
"app/advanced-development/admin/tips/page.mdx": "2024-09-10T11:39:51.165Z",
|
||||
"app/advanced-development/api-routes/cors/page.mdx": "2024-09-04T08:24:47.068Z",
|
||||
"app/advanced-development/admin/ui-routes/page.mdx": "2024-08-06T09:44:22+02:00",
|
||||
"app/advanced-development/api-routes/middlewares/page.mdx": "2024-09-04T09:45:12.441Z",
|
||||
"app/advanced-development/api-routes/middlewares/page.mdx": "2024-09-11T10:45:31.861Z",
|
||||
"app/advanced-development/modules/isolation/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/advanced-development/data-models/configure-properties/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/advanced-development/data-models/index/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/advanced-development/custom-cli-scripts/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/advanced-development/data-models/property-types/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx": "2024-09-10T11:39:51.170Z",
|
||||
"app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx": "2024-09-11T10:48:09.593Z",
|
||||
"app/debugging-and-testing/testing-tools/integration-tests/page.mdx": "2024-09-10T11:39:51.170Z",
|
||||
"app/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx": "2024-09-10T11:39:51.171Z",
|
||||
"app/debugging-and-testing/testing-tools/page.mdx": "2024-09-10T11:39:51.172Z",
|
||||
@@ -74,11 +74,11 @@ export const generatedEditDates = {
|
||||
"app/debugging-and-testing/testing-tools/unit-tests/page.mdx": "2024-09-02T11:03:26.997Z",
|
||||
"app/advanced-development/modules/service-constraints/page.mdx": "2024-09-04T15:37:04.166Z",
|
||||
"app/advanced-development/api-routes/page.mdx": "2024-09-04T09:36:33.961Z",
|
||||
"app/advanced-development/api-routes/responses/page.mdx": "2024-09-10T11:39:51.167Z",
|
||||
"app/advanced-development/api-routes/validation/page.mdx": "2024-09-10T11:39:51.167Z",
|
||||
"app/advanced-development/api-routes/responses/page.mdx": "2024-09-11T10:44:37.016Z",
|
||||
"app/advanced-development/api-routes/validation/page.mdx": "2024-09-11T10:46:31.476Z",
|
||||
"app/advanced-development/api-routes/errors/page.mdx": "2024-09-10T11:39:51.166Z",
|
||||
"app/advanced-development/admin/constraints/page.mdx": "2024-09-10T11:39:51.165Z",
|
||||
"app/advanced-development/modules/query/page.mdx": "2024-09-10T11:39:51.168Z",
|
||||
"app/advanced-development/modules/query/page.mdx": "2024-09-11T10:46:49.512Z",
|
||||
"app/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx": "2024-09-10T11:39:51.171Z",
|
||||
"app/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2024-09-10T11:39:51.171Z"
|
||||
}
|
||||
@@ -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 }) => {
|
||||
|
||||
+8
-2
@@ -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())
|
||||
|
||||
+14
-2
@@ -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 }) => {
|
||||
|
||||
+4
-4
@@ -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())
|
||||
|
||||
+16
-2
@@ -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())
|
||||
|
||||
+1
-1
@@ -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())
|
||||
|
||||
+1
-1
@@ -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())
|
||||
|
||||
+2
-2
@@ -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).
|
||||
@@ -141,7 +141,7 @@ export const generatedEditDates = {
|
||||
"app/nextjs-starter/page.mdx": "2024-07-01T10:21:19+03:00",
|
||||
"app/recipes/b2b/page.mdx": "2024-08-29T09:23:12.736Z",
|
||||
"app/recipes/commerce-automation/page.mdx": "2024-08-05T07:24:27+00:00",
|
||||
"app/recipes/digital-products/examples/standard/page.mdx": "2024-08-16T09:28:31+03:00",
|
||||
"app/recipes/digital-products/examples/standard/page.mdx": "2024-09-11T10:50:14.310Z",
|
||||
"app/recipes/digital-products/page.mdx": "2024-08-02T13:02:06+00:00",
|
||||
"app/recipes/ecommerce/page.mdx": "2024-06-09T15:18:43+02:00",
|
||||
"app/recipes/integrate-ecommerce-stack/page.mdx": "2024-08-05T07:24:27+00:00",
|
||||
@@ -150,9 +150,9 @@ export const generatedEditDates = {
|
||||
"app/recipes/multi-region-store/page.mdx": "2024-07-01T10:21:19+03:00",
|
||||
"app/recipes/omnichannel/page.mdx": "2024-06-09T15:18:43+02:00",
|
||||
"app/recipes/oms/page.mdx": "2024-07-01T10:21:19+03:00",
|
||||
"app/recipes/personalized-products/page.mdx": "2024-07-01T10:21:19+03:00",
|
||||
"app/recipes/personalized-products/page.mdx": "2024-09-11T10:53:03.936Z",
|
||||
"app/recipes/pos/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/recipes/subscriptions/examples/standard/page.mdx": "2024-08-02T12:40:26+03:00",
|
||||
"app/recipes/subscriptions/examples/standard/page.mdx": "2024-09-11T10:16:35.673Z",
|
||||
"app/recipes/subscriptions/page.mdx": "2024-08-02T12:40:26+03:00",
|
||||
"app/recipes/page.mdx": "2024-07-11T15:56:41+00:00",
|
||||
"app/service-factory-reference/methods/create/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
@@ -165,49 +165,49 @@ export const generatedEditDates = {
|
||||
"app/service-factory-reference/methods/update/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
"app/service-factory-reference/tips/filtering/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
"app/service-factory-reference/page.mdx": "2024-07-26T14:40:56+00:00",
|
||||
"app/storefront-development/cart/context/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/cart/create/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/cart/manage-items/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/cart/retrieve/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/cart/update/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/cart/context/page.mdx": "2024-09-11T10:08:05.194Z",
|
||||
"app/storefront-development/cart/create/page.mdx": "2024-09-11T10:08:05.195Z",
|
||||
"app/storefront-development/cart/manage-items/page.mdx": "2024-09-11T10:10:54.932Z",
|
||||
"app/storefront-development/cart/retrieve/page.mdx": "2024-09-11T10:12:55.828Z",
|
||||
"app/storefront-development/cart/update/page.mdx": "2024-09-11T10:12:47.704Z",
|
||||
"app/storefront-development/cart/page.mdx": "2024-06-11T11:56:37+03:00",
|
||||
"app/storefront-development/checkout/address/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/checkout/complete-cart/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/checkout/email/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/checkout/payment/stripe/page.mdx": "2024-07-01T10:21:19+03:00",
|
||||
"app/storefront-development/checkout/payment/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/checkout/shipping/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/checkout/address/page.mdx": "2024-09-11T09:40:02.899Z",
|
||||
"app/storefront-development/checkout/complete-cart/page.mdx": "2024-09-11T09:40:48.531Z",
|
||||
"app/storefront-development/checkout/email/page.mdx": "2024-09-11T09:41:22.358Z",
|
||||
"app/storefront-development/checkout/payment/stripe/page.mdx": "2024-09-11T09:41:52.777Z",
|
||||
"app/storefront-development/checkout/payment/page.mdx": "2024-09-11T09:46:55.373Z",
|
||||
"app/storefront-development/checkout/shipping/page.mdx": "2024-09-11T09:47:54.828Z",
|
||||
"app/storefront-development/checkout/page.mdx": "2024-06-12T19:46:06+02:00",
|
||||
"app/storefront-development/customers/addresses/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/customers/context/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/customers/log-out/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/customers/login/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/customers/profile/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/customers/register/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/customers/retrieve/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/customers/addresses/page.mdx": "2024-09-11T09:50:20.736Z",
|
||||
"app/storefront-development/customers/context/page.mdx": "2024-09-11T09:50:36.936Z",
|
||||
"app/storefront-development/customers/log-out/page.mdx": "2024-09-11T10:00:38.904Z",
|
||||
"app/storefront-development/customers/login/page.mdx": "2024-09-11T10:00:28.555Z",
|
||||
"app/storefront-development/customers/profile/page.mdx": "2024-09-11T09:54:38.574Z",
|
||||
"app/storefront-development/customers/register/page.mdx": "2024-09-11T09:59:29.085Z",
|
||||
"app/storefront-development/customers/retrieve/page.mdx": "2024-09-11T09:55:40.516Z",
|
||||
"app/storefront-development/customers/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/products/categories/list/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/products/categories/nested-categories/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/products/categories/products/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/products/categories/retrieve/page.mdx": "2024-06-11T19:55:56+02:00",
|
||||
"app/storefront-development/products/categories/list/page.mdx": "2024-09-11T10:01:50.873Z",
|
||||
"app/storefront-development/products/categories/nested-categories/page.mdx": "2024-09-11T10:02:28.405Z",
|
||||
"app/storefront-development/products/categories/products/page.mdx": "2024-09-11T10:08:05.194Z",
|
||||
"app/storefront-development/products/categories/retrieve/page.mdx": "2024-09-11T10:04:38.752Z",
|
||||
"app/storefront-development/products/categories/page.mdx": "2024-06-11T19:55:56+02:00",
|
||||
"app/storefront-development/products/collections/list/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/products/collections/products/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/products/collections/retrieve/page.mdx": "2024-06-11T19:55:56+02:00",
|
||||
"app/storefront-development/products/collections/list/page.mdx": "2024-09-11T10:05:31.249Z",
|
||||
"app/storefront-development/products/collections/products/page.mdx": "2024-09-11T10:08:05.205Z",
|
||||
"app/storefront-development/products/collections/retrieve/page.mdx": "2024-09-11T10:06:12.064Z",
|
||||
"app/storefront-development/products/collections/page.mdx": "2024-06-11T19:55:56+02:00",
|
||||
"app/storefront-development/products/list/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/products/price/examples/sale-price/page.mdx": "2024-07-30T12:52:21+03:00",
|
||||
"app/storefront-development/products/price/examples/show-price/page.mdx": "2024-07-30T12:52:21+03:00",
|
||||
"app/storefront-development/products/price/examples/tax-price/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
"app/storefront-development/products/price/page.mdx": "2024-09-05T14:58:05.735Z",
|
||||
"app/storefront-development/products/retrieve/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/products/variants/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/products/list/page.mdx": "2024-09-11T10:08:05.195Z",
|
||||
"app/storefront-development/products/price/examples/sale-price/page.mdx": "2024-09-11T10:08:05.204Z",
|
||||
"app/storefront-development/products/price/examples/show-price/page.mdx": "2024-09-11T10:08:05.202Z",
|
||||
"app/storefront-development/products/price/examples/tax-price/page.mdx": "2024-09-11T10:08:05.204Z",
|
||||
"app/storefront-development/products/price/page.mdx": "2024-09-11T10:08:05.202Z",
|
||||
"app/storefront-development/products/retrieve/page.mdx": "2024-09-11T10:08:05.195Z",
|
||||
"app/storefront-development/products/variants/page.mdx": "2024-09-11T10:08:05.207Z",
|
||||
"app/storefront-development/products/page.mdx": "2024-06-11T19:55:56+02:00",
|
||||
"app/storefront-development/regions/context/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/regions/list/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/regions/store-retrieve-region/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/regions/context/page.mdx": "2024-09-11T10:07:10.566Z",
|
||||
"app/storefront-development/regions/list/page.mdx": "2024-09-11T10:07:34.742Z",
|
||||
"app/storefront-development/regions/store-retrieve-region/page.mdx": "2024-09-11T10:07:42.887Z",
|
||||
"app/storefront-development/regions/page.mdx": "2024-06-09T15:19:09+02:00",
|
||||
"app/storefront-development/tips/page.mdx": "2024-06-13T12:21:54+03:00",
|
||||
"app/storefront-development/tips/page.mdx": "2024-09-11T09:25:17.014Z",
|
||||
"app/storefront-development/page.mdx": "2024-06-09T15:19:09+02:00",
|
||||
"app/troubleshooting/cors-errors/page.mdx": "2024-05-03T17:36:38+03:00",
|
||||
"app/troubleshooting/create-medusa-app-errors/page.mdx": "2024-07-11T10:29:13+03:00",
|
||||
@@ -915,7 +915,7 @@ export const generatedEditDates = {
|
||||
"references/types/interfaces/types.BaseClaim/page.mdx": "2024-09-04T00:11:02.485Z",
|
||||
"app/commerce-modules/auth/auth-providers/github/page.mdx": "2024-09-05T12:13:04.991Z",
|
||||
"app/commerce-modules/auth/auth-providers/google/page.mdx": "2024-09-05T12:12:59.196Z",
|
||||
"app/storefront-development/customers/third-party-login/page.mdx": "2024-09-05T11:35:24.269Z",
|
||||
"app/storefront-development/customers/third-party-login/page.mdx": "2024-09-11T09:58:51.801Z",
|
||||
"references/types/HttpTypes/types/types.HttpTypes.AdminWorkflowRunResponse/page.mdx": "2024-09-05T00:11:17.666Z",
|
||||
"references/types/HttpTypes/types/types.HttpTypes.BatchResponse/page.mdx": "2024-09-05T00:11:17.182Z",
|
||||
"references/types/WorkflowsSdkTypes/types/types.WorkflowsSdkTypes.Acknowledgement/page.mdx": "2024-09-05T00:11:18.150Z",
|
||||
@@ -961,7 +961,7 @@ export const generatedEditDates = {
|
||||
"references/promotion/interfaces/promotion.IPromotionModuleService/page.mdx": "2024-09-06T00:11:38.306Z",
|
||||
"references/types/EventBusTypes/interfaces/types.EventBusTypes.IEventBusService/page.mdx": "2024-09-06T00:11:07.298Z",
|
||||
"references/types/TransactionBaseTypes/interfaces/types.TransactionBaseTypes.ITransactionBaseService/page.mdx": "2024-09-06T00:11:08.494Z",
|
||||
"app/storefront-development/products/inventory/page.mdx": "2024-09-06T10:24:49.161Z",
|
||||
"app/storefront-development/products/inventory/page.mdx": "2024-09-11T10:08:05.202Z",
|
||||
"references/auth/IAuthModuleService/methods/auth.IAuthModuleService.updateAuthIdentities/page.mdx": "2024-09-06T11:11:37.710Z",
|
||||
"references/auth/IAuthModuleService/methods/auth.IAuthModuleService.updateProvider/page.mdx": "2024-09-06T11:11:37.686Z",
|
||||
"references/auth/IAuthModuleService/methods/auth.IAuthModuleService.updateProviderIdentities/page.mdx": "2024-09-06T11:11:37.726Z",
|
||||
@@ -1023,5 +1023,6 @@ export const generatedEditDates = {
|
||||
"references/order/IOrderModuleService/methods/order.IOrderModuleService.retrieveOrderChangeAction/page.mdx": "2024-09-06T11:12:03.598Z",
|
||||
"references/order/IOrderModuleService/methods/order.IOrderModuleService.updateOrderChangeActions/page.mdx": "2024-09-06T11:12:03.606Z",
|
||||
"references/types/ModulesSdkTypes/types/types.ModulesSdkTypes.RemoteQueryFunction/page.mdx": "2024-09-06T11:11:37.222Z",
|
||||
"references/types/types.CommonTypes/page.mdx": "2024-09-06T11:11:35.986Z"
|
||||
"references/types/types.CommonTypes/page.mdx": "2024-09-06T11:11:35.986Z",
|
||||
"app/storefront-development/publishable-api-keys/page.mdx": "2024-09-11T09:35:46.683Z"
|
||||
}
|
||||
@@ -859,6 +859,10 @@ export const filesMap = [
|
||||
"filePath": "/www/apps/resources/app/storefront-development/products/variants/page.mdx",
|
||||
"pathname": "/storefront-development/products/variants"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/storefront-development/publishable-api-keys/page.mdx",
|
||||
"pathname": "/storefront-development/publishable-api-keys"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/storefront-development/regions/context/page.mdx",
|
||||
"pathname": "/storefront-development/regions/context"
|
||||
|
||||
@@ -8081,6 +8081,14 @@ export const generatedSidebar = [
|
||||
"title": "Tips",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/storefront-development/publishable-api-keys",
|
||||
"title": "Publishable API Key",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
|
||||
@@ -1799,6 +1799,11 @@ export const sidebar = sidebarAttachHrefCommonOptions([
|
||||
path: "/storefront-development/tips",
|
||||
title: "Tips",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/storefront-development/publishable-api-keys",
|
||||
title: "Publishable API Key",
|
||||
},
|
||||
{
|
||||
type: "separator",
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user