diff --git a/www/apps/resources/app/architectural-modules/locking/page.mdx b/www/apps/resources/app/architectural-modules/locking/page.mdx index 0dd6c0447a..c14a9bbb2a 100644 --- a/www/apps/resources/app/architectural-modules/locking/page.mdx +++ b/www/apps/resources/app/architectural-modules/locking/page.mdx @@ -92,10 +92,10 @@ module.exports = defineConfig({ options: { providers: [ // add providers here... - ] - } - } - ] + ], + }, + }, + ], }) ``` diff --git a/www/apps/resources/app/architectural-modules/locking/postgres/page.mdx b/www/apps/resources/app/architectural-modules/locking/postgres/page.mdx index a80941e39e..03815a4a36 100644 --- a/www/apps/resources/app/architectural-modules/locking/postgres/page.mdx +++ b/www/apps/resources/app/architectural-modules/locking/postgres/page.mdx @@ -35,10 +35,10 @@ module.exports = defineConfig({ // and you have other Locking Module Providers registered. is_default: true, }, - ] - } - } - ] + ], + }, + }, + ], }) ``` @@ -75,10 +75,10 @@ module.exports = defineConfig({ id: "locking-postgres", is_default: true, }, - ] - } - } - ] + ], + }, + }, + ], }) ``` diff --git a/www/apps/resources/app/architectural-modules/locking/redis/page.mdx b/www/apps/resources/app/architectural-modules/locking/redis/page.mdx index 71a6550495..a9461d9b6e 100644 --- a/www/apps/resources/app/architectural-modules/locking/redis/page.mdx +++ b/www/apps/resources/app/architectural-modules/locking/redis/page.mdx @@ -41,12 +41,12 @@ module.exports = defineConfig({ is_default: true, options: { redisUrl: process.env.LOCKING_REDIS_URL, - } + }, }, - ] - } - } - ] + ], + }, + }, + ], }) ``` @@ -257,12 +257,12 @@ module.exports = defineConfig({ is_default: true, options: { // ... - } + }, }, - ] - } - } - ] + ], + }, + }, + ], }) ``` diff --git a/www/apps/resources/app/nextjs-starter/guides/revalidate-cache/page.mdx b/www/apps/resources/app/nextjs-starter/guides/revalidate-cache/page.mdx new file mode 100644 index 0000000000..5f78cd3af8 --- /dev/null +++ b/www/apps/resources/app/nextjs-starter/guides/revalidate-cache/page.mdx @@ -0,0 +1,88 @@ +export const metadata = { + title: `Revalidate Cache in Next.js Starter Storefront`, +} + +# {metadata.title} + +In this guide, you'll learn about the general approach to revalidating cache in the Next.js Starter Storefront when data is updated in the Medusa application. + +## Approach Overview + +By default, the data that the Next.js Starter Storefront retrieves from the Medusa application is cached in the browser. This cache is used to improve the performance and speed of the storefront. + +In some cases, you may need to revalidate the cache in the storefront when data is updated in the Medusa application. For example, when a product variant's price is updated in the Medusa application, you may want to revalidate the cache in the storefront to reflect the updated price. + +You're free to choose the approach that works for your use case, custom requirements, and tech stack. The approach that Medusa recommends is: + +1. Create a [subscriber](!docs!/learn/fundamentals/events-and-subscribers) in the Medusa application that listens for the event that triggers the data update. For example, you can listen to the `product.updated` event. +2. In the subscriber, send a request to a custom endpoint in the Next.js Starter Storefront to trigger the cache revalidation. +3. Create the custom endpoint in the Next.js Starter Storefront that listens for the request from the subscriber and revalidates the cache. + + + +Refer to the [Events Reference](../../../events-reference/page.mdx) for a full list of events that the Medusa application emits. + + + +--- + +## Example: Revalidating Cache for Product Update + +Consider you want to revalidate the cache in the Next.js Starter Storefront whenever a product is updated. + +Start by creating the following subscriber in the Medusa application: + +```ts +import type { + SubscriberArgs, + SubscriberConfig, +} from "@medusajs/framework" + +export default async function productUpdatedHandler({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + // send request to next.js storefront to revalidate cache + await fetch(`${process.env.STOREFRONT_URL}/api/revalidate?tags=products`) +} + +export const config: SubscriberConfig = { + event: "product.updated", +} +``` + +In the subscriber, you send a request to the custom endpoint `/api/revalidate` in the Next.js Starter Storefront. The request includes the query parameter `tags=product-${data.id}` to specify the cache that needs to be revalidated. + + + +Make sure to set the `STOREFRONT_URL` environment variable in the Medusa application to the URL of the Next.js Starter Storefront. + + + +Then, create in the Next.js Starter Storefront the custom endpoint that listens for the request and revalidates the cache: + +```ts title="src/app/api/revalidate/route.ts" +import { NextRequest, NextResponse } from "next/server" +import { revalidateTag } from "next/cache" +import { getCacheTag } from "../../../lib/data/cookies" + +export async function GET(req: NextRequest) { + const searchParams = req.nextUrl.searchParams + const tags = searchParams.get("tags") as string + + if (!tags) { + return NextResponse.json({ error: "No tags provided" }, { status: 400 }) + } + + const tagsArray = tags.split(",") + await Promise.all( + tagsArray.map(async (tag) => { + const cacheTag = await getCacheTag(tag) + // revalidate cache for the tag + revalidateTag(cacheTag) + }) + ) + + return NextResponse.json({ message: "Revalidated" }, { status: 200 }) +} +``` diff --git a/www/apps/resources/app/recipes/marketplace/examples/vendors/page.mdx b/www/apps/resources/app/recipes/marketplace/examples/vendors/page.mdx index 79b2b8314a..5f0878a789 100644 --- a/www/apps/resources/app/recipes/marketplace/examples/vendors/page.mdx +++ b/www/apps/resources/app/recipes/marketplace/examples/vendors/page.mdx @@ -585,7 +585,7 @@ export const vendorWorkflowHighlights = [ ```ts title="src/workflows/marketplace/create-vendor/index.ts" highlights={vendorWorkflowHighlights} import { createWorkflow, - WorkflowResponse + WorkflowResponse, } from "@medusajs/framework/workflows-sdk" import { setAuthAppMetadataStep, @@ -617,7 +617,7 @@ const createVendorWorkflow = createWorkflow( const vendorAdminData = transform({ input, - vendor + vendor, }, (data) => { return { ...data.input.admin, @@ -701,13 +701,13 @@ export const vendorRouteSchemaHighlights = [ ```ts title="src/api/vendors/route.ts" highlights={vendorRouteSchemaHighlights} import { AuthenticatedMedusaRequest, - MedusaResponse + MedusaResponse, } from "@medusajs/framework/http" import { MedusaError } from "@medusajs/framework/utils" import { z } from "zod" import createVendorWorkflow, { - CreateVendorWorkflowInput -} from "../../workflows/marketplace/create-vendor"; + CreateVendorWorkflowInput, +} from "../../workflows/marketplace/create-vendor" export const PostVendorCreateSchema = z.object({ name: z.string(), @@ -716,8 +716,8 @@ export const PostVendorCreateSchema = z.object({ admin: z.object({ email: z.string(), first_name: z.string().optional(), - last_name: z.string().optional() - }).strict() + last_name: z.string().optional(), + }).strict(), }).strict() type RequestBody = z.infer @@ -750,7 +750,7 @@ export const POST = async ( input: { ...vendorData, authIdentityId: req.auth_context.auth_identity_id, - } as CreateVendorWorkflowInput + } as CreateVendorWorkflowInput, }) res.json({ @@ -788,7 +788,7 @@ You define middlewares in Medusa in the `src/api/middlewares.ts` special file. S import { defineMiddlewares, authenticate, - validateAndTransformBody + validateAndTransformBody, } from "@medusajs/framework/http" import { PostVendorCreateSchema } from "./vendors/route" @@ -960,12 +960,12 @@ import { CreateProductWorkflowInputDTO } from "@medusajs/framework/types" import { createWorkflow, transform, - WorkflowResponse + WorkflowResponse, } from "@medusajs/framework/workflows-sdk" import { createProductsWorkflow, createRemoteLinkStep, - useQueryGraphStep + useQueryGraphStep, } from "@medusajs/medusa/core-flows" import { MARKETPLACE_MODULE } from "../../../modules/marketplace" import { Modules } from "@medusajs/framework/utils" @@ -988,22 +988,22 @@ const createVendorProductWorkflow = createWorkflow( const productData = transform({ input, - stores + stores, }, (data) => { return { products: [{ ...data.input.product, sales_channels: [ { - id: data.stores[0].default_sales_channel_id - } - ] - }] + id: data.stores[0].default_sales_channel_id, + }, + ], + }], } }) const createdProducts = createProductsWorkflow.runAsStep({ - input: productData + input: productData, }) // TODO link vendor and products @@ -1029,23 +1029,23 @@ const { data: vendorAdmins } = useQueryGraphStep({ entity: "vendor_admin", fields: ["vendor.id"], filters: { - id: input.vendor_admin_id - } + id: input.vendor_admin_id, + }, }).config({ name: "retrieve-vendor-admins" }) const linksToCreate = transform({ input, createdProducts, - vendorAdmins + vendorAdmins, }, (data) => { return data.createdProducts.map((product) => { return { [MARKETPLACE_MODULE]: { - vendor_id: data.vendorAdmins[0].vendor.id + vendor_id: data.vendorAdmins[0].vendor.id, }, [Modules.PRODUCT]: { - product_id: product.id - } + product_id: product.id, + }, } }) }) @@ -1056,12 +1056,12 @@ const { data: products } = useQueryGraphStep({ entity: "product", fields: ["*", "variants.*"], filters: { - id: createdProducts[0].id - } + id: createdProducts[0].id, + }, }).config({ name: "retrieve-products" }) return new WorkflowResponse({ - product: products[0] + product: products[0], }) ``` @@ -1086,8 +1086,8 @@ Create the file `src/api/vendors/products/route.ts` with the following content: ```ts title="src/api/vendors/products/route.ts" import { AuthenticatedMedusaRequest, - MedusaResponse -} from "@medusajs/framework/http"; + MedusaResponse, +} from "@medusajs/framework/http" import { HttpTypes, } from "@medusajs/framework/types" @@ -1101,12 +1101,12 @@ export const POST = async ( .run({ input: { vendor_admin_id: req.auth_context.actor_id, - product: req.validatedBody - } + product: req.validatedBody, + }, }) res.json({ - product: result.product + product: result.product, }) } ``` @@ -1133,9 +1133,9 @@ export default defineMiddlewares({ method: ["POST"], middlewares: [ validateAndTransformBody(AdminCreateProduct), - ] - } - ] + ], + }, + ], }) ``` @@ -1202,7 +1202,7 @@ To create the API route that retrieves the vendor’s products, add the followin ```ts title="src/api/vendors/products/route.ts" // other imports... import { - ContainerRegistrationKeys + ContainerRegistrationKeys, } from "@medusajs/framework/utils" export const GET = async ( @@ -1217,13 +1217,13 @@ export const GET = async ( filters: { id: [ // ID of the authenticated vendor admin - req.auth_context.actor_id + req.auth_context.actor_id, ], }, }) res.json({ - products: vendorAdmin.vendor.products + products: vendorAdmin.vendor.products, }) } ``` @@ -1339,8 +1339,8 @@ const groupVendorItemsStep = createStep( entity: "product", fields: ["vendor.*"], filters: { - id: [item.product_id] - } + id: [item.product_id], + }, }) const vendorId = product.vendor?.id @@ -1350,12 +1350,12 @@ const groupVendorItemsStep = createStep( } vendorsItems[vendorId] = [ ...(vendorsItems[vendorId] || []), - item + item, ] })) return new StepResponse({ - vendorsItems + vendorsItems, }) } ) @@ -1815,7 +1815,7 @@ export const getOrderHighlights = [ ] ```ts title="src/api/vendors/orders/route.ts" highlights={getOrderHighlights} -import { AuthenticatedMedusaRequest, MedusaResponse } from "@medusajs/framework/http"; +import { AuthenticatedMedusaRequest, MedusaResponse } from "@medusajs/framework/http" import { ContainerRegistrationKeys } from "@medusajs/framework/utils" import { getOrdersListWorkflow } from "@medusajs/medusa/core-flows" @@ -1829,8 +1829,8 @@ export const GET = async ( entity: "vendor_admin", fields: ["vendor.orders.*"], filters: { - id: [req.auth_context.actor_id] - } + id: [req.auth_context.actor_id], + }, }) const { result: orders } = await getOrdersListWorkflow(req.scope) @@ -1854,14 +1854,14 @@ export const GET = async ( ], variables: { filters: { - id: vendorAdmin.vendor.orders.map((order) => order.id) - } - } - } + id: vendorAdmin.vendor.orders.map((order) => order.id), + }, + }, + }, }) res.json({ - orders + orders, }) } ``` diff --git a/www/apps/resources/app/storefront-development/cart/totals/page.mdx b/www/apps/resources/app/storefront-development/cart/totals/page.mdx new file mode 100644 index 0000000000..8e7aab4c54 --- /dev/null +++ b/www/apps/resources/app/storefront-development/cart/totals/page.mdx @@ -0,0 +1,140 @@ +--- +tags: + - cart + - storefront +--- + +import { CodeTabs, CodeTab, Table } from "docs-ui" + +export const metadata = { + title: `Show Cart Totals`, +} + +# {metadata.title} + +In this guide, you'll learn how to show the cart totals in the checkout flow. This is usually shown as part of the checkout and cart pages. + +## Cart Total Fields + +The `Cart` object has various fields related to its totals, which you can check out in the [Store API reference](!api!/store#carts_cart_schema). + +The fields that are most commonly used are: + + + + + Field + Description + + + + + + `subtotal` + + + The cart's subtotal excluding taxes and shipping, and including discounts. + + + + + `discount_total` + + + The total discounts or promotions applied to the cart. + + + + + `shipping_total` + + + The total shipping cost. + + + + + `tax_total` + + + The total tax amount. + + + + + `total` + + + The total amount of the cart including all taxes, shipping, and discounts. + + + +
+ +--- + +## Example: React Storefront + +Here's an example of how you can show the cart totals in a React component: + +export const highlights = [ + ["3", "useCart", "The `useCart` hook was defined in the Cart React Context documentation."], + ["8", "formatPrice", "A function to format a price using the `Intl.NumberFormat` API."], + ["23", "formatPrice", "Show the cart's subtotal"], + ["27", "formatPrice", "Show the total discounts"], + ["31", "formatPrice", "Show the shipping total"], + ["35", "formatPrice", "Show the tax total"], + ["39", "formatPrice", "Show the total amount"], +] + +```tsx highlights={highlights} +"use client" // include with Next.js 13+ + +import { useCart } from "../../../providers/cart" + +export default function CartTotals() { + const { cart } = useCart() + + const formatPrice = (amount: number): string => { + return new Intl.NumberFormat("en-US", { + style: "currency", + currency: cart?.currency_code, + }) + .format(amount) + } + + return ( +
+ {!cart && Loading...} + {cart && ( + + )} +
+ ) +} +``` + +In the example, you first retrieve the cart using the [Cart Context](../context/page.mdx). Then, you define the [formatPrice](../retrieve/page.mdx#format-prices) function to format the total amounts. + +Finally, you render the cart totals in a list, showing the subtotal, discounts, shipping, taxes, and the total amount. diff --git a/www/apps/resources/app/storefront-development/checkout/order-confirmation/page.mdx b/www/apps/resources/app/storefront-development/checkout/order-confirmation/page.mdx new file mode 100644 index 0000000000..cccc8cab10 --- /dev/null +++ b/www/apps/resources/app/storefront-development/checkout/order-confirmation/page.mdx @@ -0,0 +1,248 @@ +--- +tags: + - order + - storefront +--- + +import { CodeTabs, CodeTab, Table } from "docs-ui" + +export const metadata = { + title: `Order Confirmation in Storefront`, +} + +# {metadata.title} + +After the customer completes the checkout process and places an order, you can show an order confirmation page to display the order details. + +In this guide, you'll learn how to show the different order details on the order confirmation page. + +## Retrieve Order Details + +To show the order details, you need to retrieve the order by sending a request to the [Get an Order API route](!api!store#orders_getordersid). + +You need the order's ID to retrieve the order. You can pass it from the [complete cart step](../complete-cart/page.mdx) or store it in the `localStorage`. + +The following example assumes you already have the order ID: + + + + +```ts +// orderId is the order ID which you can get from the complete cart step +fetch(`http://localhost:9000/store/orders/${orderId}`, { + credentials: "include", + headers: { + "x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || "temp", + }, +}) +.then((res) => res.json()) +.then(({ order }) => { + // use order... + console.log(order) +}) +``` + + + + +```tsx +"use client" // include with Next.js 13+ + +import { HttpTypes } from "@medusajs/types" +import { useEffect } from "react" +import { useState } from "react" + +export function OrderConfirmation({ id }: { id: string }) { + const [order, setOrder] = useState() + const [loading, setLoading] = useState(true) + + useEffect(() => { + fetch(`http://localhost:9000/store/orders/${id}`, { + credentials: "include", + headers: { + "x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || "temp", + }, + }) + .then((res) => res.json()) + .then(({ order: dataOrder }) => { + setOrder(dataOrder) + setLoading(false) + }) + }, [id]) + + return ( +
+ {loading && Loading...} + {!loading && order && ( +
+

Order Confirmation

+

Order ID: {order.id}

+

Order Date: {order.created_at.toLocaleString()}

+

Order Customer: {order.email}

+ {/* TODO show more info */} +
+ )} +
+ ) +} +``` + +
+
+ +In the above example, you retrieve the order's details from the [Get an Order API route](!api!store#orders_getordersid). Then, in the React example, you show the order details like the order ID, order date, and customer email. + +The rest of this guide will expand on the React example to show more order details. + + + +Refer to the [Order schema in the API reference](!api!/store#orders_order_schema) for all the available order fields. + + + +--- + +## Show Order Items + +An order has an `items` field that contains the order items. You can show the order items on the order confirmation page. + +For example, add to the React component a `formatPrice` function to format prices with the order's currency: + +```tsx +const formatPrice = (amount: number): string => { + return new Intl.NumberFormat("en-US", { + style: "currency", + currency: order?.currency_code, + }) + .format(amount) +} +``` + +Since this is the same function used to format the prices of products and cart totals, you can define the function in one place and re-use it where necessary. In that case, make sure to pass the currency code as a parameter. + +Then, you can show the order items in a list: + +```tsx +return ( +
+ {loading && Loading...} + {!loading && order && ( +
+ {/* ... */} +

+ Order Items +

    + {order.items?.map((item) => ( +
  • + {item.title} - {item.quantity} x {formatPrice(item.unit_price)} +
  • + ))} +
+

+ {/* TODO show more details */} +
+ )} +
+) +``` + +In the above example, you show the order items in a list, displaying the item's title, quantity, and unit price formatted with the `formatPrice` function. + +--- + +## Show Order Totals + +An order has various fields for the order totals, which you can check out in the [Order schema in the Store API reference](https://docs.medusajs.com/api/store#orders_order_schema). The most commonly used fields are: + + + + + Field + Description + + + + + + `subtotal` + + + The order's subtotal excluding taxes and shipping, and including discounts. + + + + + `discount_total` + + + The total discounts or promotions applied to the order. + + + + + `shipping_total` + + + The total shipping cost. + + + + + `tax_total` + + + The total tax amount. + + + + + `total` + + + The total amount of the order including all taxes, shipping, and discounts. + + + +
+ +You can show these totals on the order confirmation page. For example: + +```tsx +return ( +
+ {loading && Loading...} + {!loading && order && ( +
+ {/* ... */} +
+ Order Totals +
    +
  • + Subtotal (excl. shipping & taxes) + {formatPrice(order.subtotal ?? 0)} +
  • +
  • + Discounts + {formatPrice(order.discount_total ?? 0)} +
  • +
  • + Shipping + {formatPrice(order.shipping_total ?? 0)} +
  • +
  • + Taxes + {formatPrice(order.tax_total ?? 0)} +
  • +
  • + Total + {formatPrice(order.total ?? 0)} +
  • +
+
+
+ )} +
+) +``` + +In the above example, you show the order totals in a list, displaying the subtotal, discounts, shipping, taxes, and total amount formatted with the [formatPrice function](#show-order-items). diff --git a/www/apps/resources/app/storefront-development/checkout/page.mdx b/www/apps/resources/app/storefront-development/checkout/page.mdx index cca7de9d1d..f295639b61 100644 --- a/www/apps/resources/app/storefront-development/checkout/page.mdx +++ b/www/apps/resources/app/storefront-development/checkout/page.mdx @@ -1,5 +1,3 @@ -import { ChildDocs } from "docs-ui" - export const metadata = { title: `Checkout in Storefront`, } @@ -10,12 +8,16 @@ Once a customer finishes adding products to cart, they go through the checkout f The checkout flow is composed of five steps: -1. **Email:** Enter customer email. For logged-in customer, you can pre-fill it. -2. **Address:** Enter shipping/billing address details. -3. **Shipping**: Choose a shipping method. -4. **Payment:** Choose a payment provider. -5. **Complete Cart:** Perform any payment action necessary (for example, enter card details), complete the cart, and place the order. +1. [Email](./email/page.mdx): Enter customer email. For logged-in customer, you can pre-fill it. +2. [Address](./address/page.mdx): Enter shipping/billing address details. +3. [Shipping](./shipping/page.mdx): Choose a shipping method. +4. [Payment](./payment/page.mdx): Choose a payment provider. +5. [Complete Cart](./complete-cart/page.mdx): Perform any payment action necessary (for example, enter card details), complete the cart, and place the order. -You can combine steps based on your desired checkout flow. +You can combine steps or change their order based on your desired checkout flow. Once the customer places the order, you can show them an [order confirmation page](./order-confirmation/page.mdx). - \ No newline at end of file + + +Refer to the [Express Checkout Tutorial](../guides/express-checkout/page.mdx) for a complete example of a different checkout flow. + + diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index ecd879ccf9..5fe331f1b9 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -6057,5 +6057,8 @@ export const generatedEditDates = { "references/modules/event/page.mdx": "2025-03-17T15:24:03.021Z", "references/modules/file_service/page.mdx": "2025-03-17T15:24:03.025Z", "references/modules/notification_service/page.mdx": "2025-03-17T15:24:05.164Z", - "references/notification_service/interfaces/notification_service.INotificationModuleService/page.mdx": "2025-03-17T15:24:05.173Z" + "references/notification_service/interfaces/notification_service.INotificationModuleService/page.mdx": "2025-03-17T15:24:05.173Z", + "app/nextjs-starter/guides/revalidate-cache/page.mdx": "2025-03-18T08:47:59.628Z", + "app/storefront-development/cart/totals/page.mdx": "2025-03-18T09:20:59.533Z", + "app/storefront-development/checkout/order-confirmation/page.mdx": "2025-03-18T09:44:14.561Z" } \ 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 b2251be626..12fa82fb9f 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -891,6 +891,10 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/nextjs-starter/guides/customize-stripe/page.mdx", "pathname": "/nextjs-starter/guides/customize-stripe" }, + { + "filePath": "/www/apps/resources/app/nextjs-starter/guides/revalidate-cache/page.mdx", + "pathname": "/nextjs-starter/guides/revalidate-cache" + }, { "filePath": "/www/apps/resources/app/nextjs-starter/page.mdx", "pathname": "/nextjs-starter" @@ -1039,6 +1043,10 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/storefront-development/cart/retrieve/page.mdx", "pathname": "/storefront-development/cart/retrieve" }, + { + "filePath": "/www/apps/resources/app/storefront-development/cart/totals/page.mdx", + "pathname": "/storefront-development/cart/totals" + }, { "filePath": "/www/apps/resources/app/storefront-development/cart/update/page.mdx", "pathname": "/storefront-development/cart/update" @@ -1055,6 +1063,10 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/storefront-development/checkout/email/page.mdx", "pathname": "/storefront-development/checkout/email" }, + { + "filePath": "/www/apps/resources/app/storefront-development/checkout/order-confirmation/page.mdx", + "pathname": "/storefront-development/checkout/order-confirmation" + }, { "filePath": "/www/apps/resources/app/storefront-development/checkout/page.mdx", "pathname": "/storefront-development/checkout" diff --git a/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs b/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs index 5cdfc39872..e0ed70b892 100644 --- a/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs +++ b/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs @@ -1195,6 +1195,14 @@ const generatedgeneratedCommerceModulesSidebarSidebar = { "path": "https://docs.medusajs.com/resources/storefront-development/cart/retrieve", "children": [] }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Show Cart Totals", + "path": "https://docs.medusajs.com/resources/storefront-development/cart/totals", + "children": [] + }, { "loaded": true, "isPathHref": true, @@ -5957,6 +5965,14 @@ const generatedgeneratedCommerceModulesSidebarSidebar = { "title": "Implement Express Checkout with Medusa", "path": "https://docs.medusajs.com/resources/storefront-development/guides/express-checkout", "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Order Confirmation in Storefront", + "path": "https://docs.medusajs.com/resources/storefront-development/checkout/order-confirmation", + "children": [] } ] }, diff --git a/www/apps/resources/generated/generated-storefront-development-sidebar.mjs b/www/apps/resources/generated/generated-storefront-development-sidebar.mjs index 814d0dd918..f0652a9570 100644 --- a/www/apps/resources/generated/generated-storefront-development-sidebar.mjs +++ b/www/apps/resources/generated/generated-storefront-development-sidebar.mjs @@ -293,6 +293,14 @@ const generatedgeneratedStorefrontDevelopmentSidebarSidebar = { "path": "/storefront-development/cart/manage-items", "title": "Manage Line Items", "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/storefront-development/cart/totals", + "title": "Show Totals", + "children": [] } ] }, @@ -359,6 +367,14 @@ const generatedgeneratedStorefrontDevelopmentSidebarSidebar = { "path": "/storefront-development/checkout/complete-cart", "title": "5. Complete Cart", "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/storefront-development/checkout/order-confirmation", + "title": "Show Order Confirmation", + "children": [] } ] }, diff --git a/www/apps/resources/generated/generated-tools-sidebar.mjs b/www/apps/resources/generated/generated-tools-sidebar.mjs index fa5922f4ae..663002618d 100644 --- a/www/apps/resources/generated/generated-tools-sidebar.mjs +++ b/www/apps/resources/generated/generated-tools-sidebar.mjs @@ -756,7 +756,7 @@ const generatedgeneratedToolsSidebarSidebar = { "loaded": true, "isPathHref": true, "type": "category", - "title": "Payment", + "title": "How-to Guides", "initialOpen": true, "children": [ { @@ -766,6 +766,14 @@ const generatedgeneratedToolsSidebarSidebar = { "path": "/nextjs-starter/guides/customize-stripe", "title": "Customize Stripe Integration", "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/nextjs-starter/guides/revalidate-cache", + "title": "Revalidate Cache", + "children": [] } ] } diff --git a/www/apps/resources/sidebars/storefront.mjs b/www/apps/resources/sidebars/storefront.mjs index 3b88602d76..aa2c2c800d 100644 --- a/www/apps/resources/sidebars/storefront.mjs +++ b/www/apps/resources/sidebars/storefront.mjs @@ -179,6 +179,11 @@ export const storefrontDevelopmentSidebar = [ path: "/storefront-development/cart/manage-items", title: "Manage Line Items", }, + { + type: "link", + path: "/storefront-development/cart/totals", + title: "Show Totals", + }, ], }, { @@ -224,6 +229,11 @@ export const storefrontDevelopmentSidebar = [ path: "/storefront-development/checkout/complete-cart", title: "5. Complete Cart", }, + { + type: "link", + path: "/storefront-development/checkout/order-confirmation", + title: "Show Order Confirmation", + }, ], }, { diff --git a/www/apps/resources/sidebars/tools.mjs b/www/apps/resources/sidebars/tools.mjs index 0feba51f59..fa80ebf624 100644 --- a/www/apps/resources/sidebars/tools.mjs +++ b/www/apps/resources/sidebars/tools.mjs @@ -100,7 +100,7 @@ export const toolsSidebar = [ }, { type: "category", - title: "Payment", + title: "How-to Guides", initialOpen: true, children: [ { @@ -108,6 +108,11 @@ export const toolsSidebar = [ path: "/nextjs-starter/guides/customize-stripe", title: "Customize Stripe Integration", }, + { + type: "link", + path: "/nextjs-starter/guides/revalidate-cache", + title: "Revalidate Cache", + }, ], }, ], diff --git a/www/packages/tags/src/tags/cart.ts b/www/packages/tags/src/tags/cart.ts index 9b1425d5e9..1730992fc5 100644 --- a/www/packages/tags/src/tags/cart.ts +++ b/www/packages/tags/src/tags/cart.ts @@ -27,6 +27,10 @@ export const cart = [ "title": "Retrieve Cart in Storefront", "path": "https://docs.medusajs.com/resources/storefront-development/cart/retrieve" }, + { + "title": "Show Cart Totals", + "path": "https://docs.medusajs.com/resources/storefront-development/cart/totals" + }, { "title": "Update Cart in Storefront", "path": "https://docs.medusajs.com/resources/storefront-development/cart/update" diff --git a/www/packages/tags/src/tags/order.ts b/www/packages/tags/src/tags/order.ts index 7e35fb081a..9d31aba3e1 100644 --- a/www/packages/tags/src/tags/order.ts +++ b/www/packages/tags/src/tags/order.ts @@ -43,6 +43,10 @@ export const order = [ "title": "Checkout Step 5: Complete Cart", "path": "https://docs.medusajs.com/resources/storefront-development/checkout/complete-cart" }, + { + "title": "Order Confirmation in Storefront", + "path": "https://docs.medusajs.com/resources/storefront-development/checkout/order-confirmation" + }, { "title": "Implement Express Checkout with Medusa", "path": "https://docs.medusajs.com/resources/storefront-development/guides/express-checkout" diff --git a/www/packages/tags/src/tags/storefront.ts b/www/packages/tags/src/tags/storefront.ts index 1c38518369..45ffac6fe3 100644 --- a/www/packages/tags/src/tags/storefront.ts +++ b/www/packages/tags/src/tags/storefront.ts @@ -19,6 +19,10 @@ export const storefront = [ "title": "Retrieve Cart in Storefront", "path": "https://docs.medusajs.com/resources/storefront-development/cart/retrieve" }, + { + "title": "Show Cart Totals", + "path": "https://docs.medusajs.com/resources/storefront-development/cart/totals" + }, { "title": "Update Cart in Storefront", "path": "https://docs.medusajs.com/resources/storefront-development/cart/update" @@ -35,6 +39,10 @@ export const storefront = [ "title": "Checkout Step 1: Enter Email", "path": "https://docs.medusajs.com/resources/storefront-development/checkout/email" }, + { + "title": "Order Confirmation in Storefront", + "path": "https://docs.medusajs.com/resources/storefront-development/checkout/order-confirmation" + }, { "title": "Checkout Step 4: Choose Payment Provider", "path": "https://docs.medusajs.com/resources/storefront-development/checkout/payment"