diff --git a/www/apps/api-reference/app/_mdx/store.mdx b/www/apps/api-reference/app/_mdx/store.mdx index 72a6cf0b99..0a2899bf99 100644 --- a/www/apps/api-reference/app/_mdx/store.mdx +++ b/www/apps/api-reference/app/_mdx/store.mdx @@ -140,34 +140,31 @@ fetch(`/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. + -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. diff --git a/www/apps/book/app/advanced-development/api-routes/responses/page.mdx b/www/apps/book/app/advanced-development/api-routes/responses/page.mdx index 45ea20b3dc..a24f0b8761 100644 --- a/www/apps/book/app/advanced-development/api-routes/responses/page.mdx +++ b/www/apps/book/app/advanced-development/api-routes/responses/page.mdx @@ -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 ( diff --git a/www/apps/book/app/advanced-development/api-routes/validation/page.mdx b/www/apps/book/app/advanced-development/api-routes/validation/page.mdx index e4b76188db..4a6d3e3489 100644 --- a/www/apps/book/app/advanced-development/api-routes/validation/page.mdx +++ b/www/apps/book/app/advanced-development/api-routes/validation/page.mdx @@ -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: diff --git a/www/apps/book/app/advanced-development/modules/query/page.mdx b/www/apps/book/app/advanced-development/modules/query/page.mdx index 0b81c2e04d..5ea407e4b4 100644 --- a/www/apps/book/app/advanced-development/modules/query/page.mdx +++ b/www/apps/book/app/advanced-development/modules/query/page.mdx @@ -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, diff --git a/www/apps/book/app/advanced-development/workflows/access-workflow-errors/page.mdx b/www/apps/book/app/advanced-development/workflows/access-workflow-errors/page.mdx index 42f2087d61..e9d66806e1 100644 --- a/www/apps/book/app/advanced-development/workflows/access-workflow-errors/page.mdx +++ b/www/apps/book/app/advanced-development/workflows/access-workflow-errors/page.mdx @@ -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, diff --git a/www/apps/book/app/advanced-development/workflows/advanced-example/page.mdx b/www/apps/book/app/advanced-development/workflows/advanced-example/page.mdx index 6b2c1ec9d2..68e49b43d9 100644 --- a/www/apps/book/app/advanced-development/workflows/advanced-example/page.mdx +++ b/www/apps/book/app/advanced-development/workflows/advanced-example/page.mdx @@ -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, diff --git a/www/apps/book/app/advanced-development/workflows/compensation-function/page.mdx b/www/apps/book/app/advanced-development/workflows/compensation-function/page.mdx index 9577aab9f0..98d790bec5 100644 --- a/www/apps/book/app/advanced-development/workflows/compensation-function/page.mdx +++ b/www/apps/book/app/advanced-development/workflows/compensation-function/page.mdx @@ -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: diff --git a/www/apps/book/app/advanced-development/workflows/long-running-workflow/page.mdx b/www/apps/book/app/advanced-development/workflows/long-running-workflow/page.mdx index eb1eeb5921..567a841f01 100644 --- a/www/apps/book/app/advanced-development/workflows/long-running-workflow/page.mdx +++ b/www/apps/book/app/advanced-development/workflows/long-running-workflow/page.mdx @@ -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 { diff --git a/www/apps/book/app/basics/api-routes/page.mdx b/www/apps/book/app/basics/api-routes/page.mdx index e76af22079..80e881288a 100644 --- a/www/apps/book/app/basics/api-routes/page.mdx +++ b/www/apps/book/app/basics/api-routes/page.mdx @@ -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 ``` --- diff --git a/www/apps/book/app/basics/modules-and-services/page.mdx b/www/apps/book/app/basics/modules-and-services/page.mdx index 69627acb40..500030b129 100644 --- a/www/apps/book/app/basics/modules-and-services/page.mdx +++ b/www/apps/book/app/basics/modules-and-services/page.mdx @@ -105,9 +105,9 @@ Resolving a module's service is essential to use its methods that perform action -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: diff --git a/www/apps/book/app/basics/workflows/page.mdx b/www/apps/book/app/basics/workflows/page.mdx index 4af4e58b3b..7a04688933 100644 --- a/www/apps/book/app/basics/workflows/page.mdx +++ b/www/apps/book/app/basics/workflows/page.mdx @@ -96,7 +96,7 @@ To execute the workflow, invoke it passing the Medusa container as a parameter. - ```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: diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx index e02486f7e6..eb30944739 100644 --- a/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx +++ b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx @@ -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. diff --git a/www/apps/book/app/first-customizations/page.mdx b/www/apps/book/app/first-customizations/page.mdx index 2cab68f589..8cdbe18d8a 100644 --- a/www/apps/book/app/first-customizations/page.mdx +++ b/www/apps/book/app/first-customizations/page.mdx @@ -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: diff --git a/www/apps/book/app/storefront-development/page.mdx b/www/apps/book/app/storefront-development/page.mdx index 4dbf5ab50b..9c456e8961 100644 --- a/www/apps/book/app/storefront-development/page.mdx +++ b/www/apps/book/app/storefront-development/page.mdx @@ -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. + +--- + +## 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). diff --git a/www/apps/book/generated/edit-dates.mjs b/www/apps/book/generated/edit-dates.mjs index 0e14c13afc..c346fd5a05 100644 --- a/www/apps/book/generated/edit-dates.mjs +++ b/www/apps/book/generated/edit-dates.mjs @@ -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" } \ No newline at end of file diff --git a/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx b/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx index 59c739796c..337e5c2953 100644 --- a/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx +++ b/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx @@ -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()) diff --git a/www/apps/resources/app/recipes/marketplace/examples/restaurant-delivery/page.mdx b/www/apps/resources/app/recipes/marketplace/examples/restaurant-delivery/page.mdx index e0398f00ad..dabfca141f 100644 --- a/www/apps/resources/app/recipes/marketplace/examples/restaurant-delivery/page.mdx +++ b/www/apps/resources/app/recipes/marketplace/examples/restaurant-delivery/page.mdx @@ -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. diff --git a/www/apps/resources/app/recipes/personalized-products/page.mdx b/www/apps/resources/app/recipes/personalized-products/page.mdx index 990e62e2df..29c720868a 100644 --- a/www/apps/resources/app/recipes/personalized-products/page.mdx +++ b/www/apps/resources/app/recipes/personalized-products/page.mdx @@ -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, diff --git a/www/apps/resources/app/recipes/subscriptions/examples/standard/page.mdx b/www/apps/resources/app/recipes/subscriptions/examples/standard/page.mdx index 402099383b..0953ac20b7 100644 --- a/www/apps/resources/app/recipes/subscriptions/examples/standard/page.mdx +++ b/www/apps/resources/app/recipes/subscriptions/examples/standard/page.mdx @@ -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}' ``` --- diff --git a/www/apps/resources/app/storefront-development/cart/context/page.mdx b/www/apps/resources/app/storefront-development/cart/context/page.mdx index 53a11dd935..9b57ce38c7 100644 --- a/www/apps/resources/app/storefront-development/cart/context/page.mdx +++ b/www/apps/resources/app/storefront-development/cart/context/page.mdx @@ -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 }) => { diff --git a/www/apps/resources/app/storefront-development/cart/create/page.mdx b/www/apps/resources/app/storefront-development/cart/create/page.mdx index 1ac67ef409..446d909119 100644 --- a/www/apps/resources/app/storefront-development/cart/create/page.mdx +++ b/www/apps/resources/app/storefront-development/cart/create/page.mdx @@ -20,7 +20,7 @@ For example: 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({ diff --git a/www/apps/resources/app/storefront-development/cart/manage-items/page.mdx b/www/apps/resources/app/storefront-development/cart/manage-items/page.mdx index 62245bbcc5..7f0b476eac 100644 --- a/www/apps/resources/app/storefront-development/cart/manage-items/page.mdx +++ b/www/apps/resources/app/storefront-development/cart/manage-items/page.mdx @@ -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()) diff --git a/www/apps/resources/app/storefront-development/cart/retrieve/page.mdx b/www/apps/resources/app/storefront-development/cart/retrieve/page.mdx index 80727ad64a..871a8819c1 100644 --- a/www/apps/resources/app/storefront-development/cart/retrieve/page.mdx +++ b/www/apps/resources/app/storefront-development/cart/retrieve/page.mdx @@ -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 }) => { diff --git a/www/apps/resources/app/storefront-development/cart/update/page.mdx b/www/apps/resources/app/storefront-development/cart/update/page.mdx index e1cc75018f..e8a3a972a0 100644 --- a/www/apps/resources/app/storefront-development/cart/update/page.mdx +++ b/www/apps/resources/app/storefront-development/cart/update/page.mdx @@ -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", diff --git a/www/apps/resources/app/storefront-development/checkout/address/page.mdx b/www/apps/resources/app/storefront-development/checkout/address/page.mdx index 989417d95a..f89eec51c9 100644 --- a/www/apps/resources/app/storefront-development/checkout/address/page.mdx +++ b/www/apps/resources/app/storefront-development/checkout/address/page.mdx @@ -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, diff --git a/www/apps/resources/app/storefront-development/checkout/complete-cart/page.mdx b/www/apps/resources/app/storefront-development/checkout/complete-cart/page.mdx index ea58531a66..f719598713 100644 --- a/www/apps/resources/app/storefront-development/checkout/complete-cart/page.mdx +++ b/www/apps/resources/app/storefront-development/checkout/complete-cart/page.mdx @@ -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", } ) diff --git a/www/apps/resources/app/storefront-development/checkout/email/page.mdx b/www/apps/resources/app/storefront-development/checkout/email/page.mdx index addc44b079..07df4bc8ad 100644 --- a/www/apps/resources/app/storefront-development/checkout/email/page.mdx +++ b/www/apps/resources/app/storefront-development/checkout/email/page.mdx @@ -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, diff --git a/www/apps/resources/app/storefront-development/checkout/payment/page.mdx b/www/apps/resources/app/storefront-development/checkout/payment/page.mdx index f96505a0fe..da5bbdc834 100644 --- a/www/apps/resources/app/storefront-development/checkout/payment/page.mdx +++ b/www/apps/resources/app/storefront-development/checkout/payment/page.mdx @@ -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()) diff --git a/www/apps/resources/app/storefront-development/checkout/payment/stripe/page.mdx b/www/apps/resources/app/storefront-development/checkout/payment/stripe/page.mdx index aeaaac27f8..9313518db1 100644 --- a/www/apps/resources/app/storefront-development/checkout/payment/stripe/page.mdx +++ b/www/apps/resources/app/storefront-development/checkout/payment/stripe/page.mdx @@ -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", } ) diff --git a/www/apps/resources/app/storefront-development/checkout/shipping/page.mdx b/www/apps/resources/app/storefront-development/checkout/shipping/page.mdx index 2d4d51d27e..13bcf171c3 100644 --- a/www/apps/resources/app/storefront-development/checkout/shipping/page.mdx +++ b/www/apps/resources/app/storefront-development/checkout/shipping/page.mdx @@ -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, diff --git a/www/apps/resources/app/storefront-development/customers/addresses/page.mdx b/www/apps/resources/app/storefront-development/customers/addresses/page.mdx index bde76f6fdc..1f3fccc247 100644 --- a/www/apps/resources/app/storefront-development/customers/addresses/page.mdx +++ b/www/apps/resources/app/storefront-development/customers/addresses/page.mdx @@ -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", } ) diff --git a/www/apps/resources/app/storefront-development/customers/context/page.mdx b/www/apps/resources/app/storefront-development/customers/context/page.mdx index afea21246a..66879fbd14 100644 --- a/www/apps/resources/app/storefront-development/customers/context/page.mdx +++ b/www/apps/resources/app/storefront-development/customers/context/page.mdx @@ -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 }) => { diff --git a/www/apps/resources/app/storefront-development/customers/log-out/page.mdx b/www/apps/resources/app/storefront-development/customers/log-out/page.mdx index 9a7aa615ce..a6d9c63f69 100644 --- a/www/apps/resources/app/storefront-development/customers/log-out/page.mdx +++ b/www/apps/resources/app/storefront-development/customers/log-out/page.mdx @@ -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" diff --git a/www/apps/resources/app/storefront-development/customers/login/page.mdx b/www/apps/resources/app/storefront-development/customers/login/page.mdx index c30907a924..188a8ad001 100644 --- a/www/apps/resources/app/storefront-development/customers/login/page.mdx +++ b/www/apps/resources/app/storefront-development/customers/login/page.mdx @@ -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, }, } ) diff --git a/www/apps/resources/app/storefront-development/customers/profile/page.mdx b/www/apps/resources/app/storefront-development/customers/profile/page.mdx index a2cc749e62..7a6d614420 100644 --- a/www/apps/resources/app/storefront-development/customers/profile/page.mdx +++ b/www/apps/resources/app/storefront-development/customers/profile/page.mdx @@ -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, diff --git a/www/apps/resources/app/storefront-development/customers/register/page.mdx b/www/apps/resources/app/storefront-development/customers/register/page.mdx index d69d721935..4716dc2d63 100644 --- a/www/apps/resources/app/storefront-development/customers/register/page.mdx +++ b/www/apps/resources/app/storefront-development/customers/register/page.mdx @@ -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, diff --git a/www/apps/resources/app/storefront-development/customers/retrieve/page.mdx b/www/apps/resources/app/storefront-development/customers/retrieve/page.mdx index 56ad3689c7..47719396f8 100644 --- a/www/apps/resources/app/storefront-development/customers/retrieve/page.mdx +++ b/www/apps/resources/app/storefront-development/customers/retrieve/page.mdx @@ -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, }, } ) diff --git a/www/apps/resources/app/storefront-development/customers/third-party-login/page.mdx b/www/apps/resources/app/storefront-development/customers/third-party-login/page.mdx index 2abd30a742..831a436d33 100644 --- a/www/apps/resources/app/storefront-development/customers/third-party-login/page.mdx +++ b/www/apps/resources/app/storefront-development/customers/third-party-login/page.mdx @@ -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 diff --git a/www/apps/resources/app/storefront-development/products/categories/list/page.mdx b/www/apps/resources/app/storefront-development/products/categories/list/page.mdx index f231050e24..2d7312f91b 100644 --- a/www/apps/resources/app/storefront-development/products/categories/list/page.mdx +++ b/www/apps/resources/app/storefront-development/products/categories/list/page.mdx @@ -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 }) => { diff --git a/www/apps/resources/app/storefront-development/products/categories/nested-categories/page.mdx b/www/apps/resources/app/storefront-development/products/categories/nested-categories/page.mdx index d04c57f13b..63740305a4 100644 --- a/www/apps/resources/app/storefront-development/products/categories/nested-categories/page.mdx +++ b/www/apps/resources/app/storefront-development/products/categories/nested-categories/page.mdx @@ -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 }) => { diff --git a/www/apps/resources/app/storefront-development/products/categories/products/page.mdx b/www/apps/resources/app/storefront-development/products/categories/products/page.mdx index 58897e5d6b..e73cd6160f 100644 --- a/www/apps/resources/app/storefront-development/products/categories/products/page.mdx +++ b/www/apps/resources/app/storefront-development/products/categories/products/page.mdx @@ -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()) diff --git a/www/apps/resources/app/storefront-development/products/categories/retrieve/page.mdx b/www/apps/resources/app/storefront-development/products/categories/retrieve/page.mdx index dbd8e718c7..eef5e797f1 100644 --- a/www/apps/resources/app/storefront-development/products/categories/retrieve/page.mdx +++ b/www/apps/resources/app/storefront-development/products/categories/retrieve/page.mdx @@ -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 }) => { diff --git a/www/apps/resources/app/storefront-development/products/collections/list/page.mdx b/www/apps/resources/app/storefront-development/products/collections/list/page.mdx index 636d2f6bbd..adace6b01c 100644 --- a/www/apps/resources/app/storefront-development/products/collections/list/page.mdx +++ b/www/apps/resources/app/storefront-development/products/collections/list/page.mdx @@ -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 }) => { diff --git a/www/apps/resources/app/storefront-development/products/collections/products/page.mdx b/www/apps/resources/app/storefront-development/products/collections/products/page.mdx index b512ec1b9c..aa44a73fcb 100644 --- a/www/apps/resources/app/storefront-development/products/collections/products/page.mdx +++ b/www/apps/resources/app/storefront-development/products/collections/products/page.mdx @@ -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()) diff --git a/www/apps/resources/app/storefront-development/products/collections/retrieve/page.mdx b/www/apps/resources/app/storefront-development/products/collections/retrieve/page.mdx index 1aad9a48da..a99eea35be 100644 --- a/www/apps/resources/app/storefront-development/products/collections/retrieve/page.mdx +++ b/www/apps/resources/app/storefront-development/products/collections/retrieve/page.mdx @@ -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 }) => { diff --git a/www/apps/resources/app/storefront-development/products/inventory/page.mdx b/www/apps/resources/app/storefront-development/products/inventory/page.mdx index 4322c720d3..6fcc3eab68 100644 --- a/www/apps/resources/app/storefront-development/products/inventory/page.mdx +++ b/www/apps/resources/app/storefront-development/products/inventory/page.mdx @@ -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()) diff --git a/www/apps/resources/app/storefront-development/products/list/page.mdx b/www/apps/resources/app/storefront-development/products/list/page.mdx index 2a0cb007c8..9547552a77 100644 --- a/www/apps/resources/app/storefront-development/products/list/page.mdx +++ b/www/apps/resources/app/storefront-development/products/list/page.mdx @@ -16,14 +16,14 @@ To list products, send a request to the [List Products API route](!api!/store#pr 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()) diff --git a/www/apps/resources/app/storefront-development/products/price/examples/sale-price/page.mdx b/www/apps/resources/app/storefront-development/products/price/examples/sale-price/page.mdx index 3e62a147c2..6a79fbc966 100644 --- a/www/apps/resources/app/storefront-development/products/price/examples/sale-price/page.mdx +++ b/www/apps/resources/app/storefront-development/products/price/examples/sale-price/page.mdx @@ -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()) diff --git a/www/apps/resources/app/storefront-development/products/price/examples/show-price/page.mdx b/www/apps/resources/app/storefront-development/products/price/examples/show-price/page.mdx index 5f502628a6..c540d6c8e7 100644 --- a/www/apps/resources/app/storefront-development/products/price/examples/show-price/page.mdx +++ b/www/apps/resources/app/storefront-development/products/price/examples/show-price/page.mdx @@ -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()) diff --git a/www/apps/resources/app/storefront-development/products/price/examples/tax-price/page.mdx b/www/apps/resources/app/storefront-development/products/price/examples/tax-price/page.mdx index 6d8c946f47..75b8776d6c 100644 --- a/www/apps/resources/app/storefront-development/products/price/examples/tax-price/page.mdx +++ b/www/apps/resources/app/storefront-development/products/price/examples/tax-price/page.mdx @@ -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()) diff --git a/www/apps/resources/app/storefront-development/products/price/page.mdx b/www/apps/resources/app/storefront-development/products/price/page.mdx index f6acb87451..817ab96ca1 100644 --- a/www/apps/resources/app/storefront-development/products/price/page.mdx +++ b/www/apps/resources/app/storefront-development/products/price/page.mdx @@ -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()) diff --git a/www/apps/resources/app/storefront-development/products/retrieve/page.mdx b/www/apps/resources/app/storefront-development/products/retrieve/page.mdx index 480f2e6b7d..333a40590f 100644 --- a/www/apps/resources/app/storefront-development/products/retrieve/page.mdx +++ b/www/apps/resources/app/storefront-development/products/retrieve/page.mdx @@ -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()) diff --git a/www/apps/resources/app/storefront-development/products/variants/page.mdx b/www/apps/resources/app/storefront-development/products/variants/page.mdx index 7f33c06654..d808d3a7ac 100644 --- a/www/apps/resources/app/storefront-development/products/variants/page.mdx +++ b/www/apps/resources/app/storefront-development/products/variants/page.mdx @@ -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()) diff --git a/www/apps/resources/app/storefront-development/publishable-api-keys/page.mdx b/www/apps/resources/app/storefront-development/publishable-api-keys/page.mdx new file mode 100644 index 0000000000..e04ad8a80b --- /dev/null +++ b/www/apps/resources/app/storefront-development/publishable-api-keys/page.mdx @@ -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" +}' +``` + + + +Learn how to send authenticated admin requests in the [Admin API reference](!api!/admin#authentication) + + + +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. diff --git a/www/apps/resources/app/storefront-development/regions/context/page.mdx b/www/apps/resources/app/storefront-development/regions/context/page.mdx index 313682ff9d..976c3293d6 100644 --- a/www/apps/resources/app/storefront-development/regions/context/page.mdx +++ b/www/apps/resources/app/storefront-development/regions/context/page.mdx @@ -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 }) => { diff --git a/www/apps/resources/app/storefront-development/regions/list/page.mdx b/www/apps/resources/app/storefront-development/regions/list/page.mdx index 9608c6fb0d..fb21e0c3e0 100644 --- a/www/apps/resources/app/storefront-development/regions/list/page.mdx +++ b/www/apps/resources/app/storefront-development/regions/list/page.mdx @@ -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 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 }) => { diff --git a/www/apps/resources/app/storefront-development/regions/store-retrieve-region/page.mdx b/www/apps/resources/app/storefront-development/regions/store-retrieve-region/page.mdx index 6679a88762..bc1fb4eb2f 100644 --- a/www/apps/resources/app/storefront-development/regions/store-retrieve-region/page.mdx +++ b/www/apps/resources/app/storefront-development/regions/store-retrieve-region/page.mdx @@ -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 }) => { diff --git a/www/apps/resources/app/storefront-development/tips/page.mdx b/www/apps/resources/app/storefront-development/tips/page.mdx index 79d23a1d3e..b7342cdea8 100644 --- a/www/apps/resources/app/storefront-development/tips/page.mdx +++ b/www/apps/resources/app/storefront-development/tips/page.mdx @@ -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. - - - -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. - - - -{/* 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). diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 4d5d8d9f6c..49b6f3b294 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -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" } \ No newline at end of file diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 416efb0f3f..4610aab193 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -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" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index d92689dc65..aea26b89ff 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -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" }, diff --git a/www/apps/resources/sidebar.mjs b/www/apps/resources/sidebar.mjs index e77f6128b8..3bac0ff6d4 100644 --- a/www/apps/resources/sidebar.mjs +++ b/www/apps/resources/sidebar.mjs @@ -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", },