### Install Dependencies Source: https://github.com/medusajs/nextjs-starter-medusa/blob/main/README.md Install all project dependencies using Yarn. ```shell yarn ``` -------------------------------- ### Start Development Server Source: https://github.com/medusajs/nextjs-starter-medusa/blob/main/README.md Start the development server to run your project locally. The site will be available at http://localhost:8000. ```shell yarn dev ``` -------------------------------- ### Install Medusa App Source: https://github.com/medusajs/nextjs-starter-medusa/blob/main/README.md Use this command to create a new Medusa app locally. Refer to the Medusa documentation for more details. ```shell npx create-medusa-app@latest ``` -------------------------------- ### Format amounts and get product prices Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Use `convertToLocale` to format raw amounts into locale-aware currency strings. `getProductPrice` and `getPricesForVariant` extract pricing details from product data. ```typescript import { convertToLocale } from "@lib/util/money" import { getProductPrice, getPricesForVariant } from "@lib/util/get-product-price" // Format a raw amount (in minor units) as a currency string: convertToLocale({ amount: 2999, currency_code: "usd", locale: "en-US" }) // → "$29.99" convertToLocale({ amount: 1500, currency_code: "eur", locale: "de-DE" }) // → "15,00 €" // Get cheapest and selected-variant prices for a product: const { cheapestPrice, variantPrice } = getProductPrice({ product, // HttpTypes.StoreProduct with calculated_price on variants variantId: "variant_01JXYZ", // optional }) // cheapestPrice / variantPrice shape: // { // calculated_price: "$19.99", // calculated_price_number: 1999, // original_price: "$24.99", // original_price_number: 2499, // currency_code: "usd", // price_type: "sale", // percentage_diff: "20" ← from getPercentageDiff() // } ``` -------------------------------- ### Medusa Next.js Starter Environment Configuration Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Configure required and optional environment variables for the Medusa Next.js Starter. This includes backend URL, publishable key, payment provider keys, default region, and S3 image hosting details. ```shell # Required MEDUSA_BACKEND_URL=http://localhost:9000 NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_... # Optional — payment NEXT_PUBLIC_STRIPE_KEY=pk_test_... # Optional — default region fallback NEXT_PUBLIC_DEFAULT_REGION=us # Optional — Medusa Cloud S3 image hosting MEDUSA_CLOUD_S3_HOSTNAME=my-bucket.s3.eu-west-1.amazonaws.com MEDUSA_CLOUD_S3_PATHNAME=/images/** ``` -------------------------------- ### Configure Environment Variables Source: https://github.com/medusajs/nextjs-starter-medusa/blob/main/README.md Navigate to your project directory and copy the template environment file to `.env.local` to set up your environment variables. ```shell cd nextjs-starter-medusa/ mv .env.template .env.local ``` -------------------------------- ### Initialize Medusa JS SDK Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Instantiates the Medusa JS SDK singleton. Injects the 'x-medusa-locale' header on every request by wrapping the client's fetch method. Requires MEDUSA_BACKEND_URL and NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY environment variables. ```typescript import Medusa from "@medusajs/js-sdk" export const sdk = new Medusa({ baseUrl: process.env.MEDUSA_BACKEND_URL || "http://localhost:9000", debug: process.env.NODE_ENV === "development", publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY, }) // The fetch method is wrapped to automatically forward the locale cookie // as the "x-medusa-locale" header on every request. ``` -------------------------------- ### Configure Stripe Payment Integration Source: https://github.com/medusajs/nextjs-starter-medusa/blob/main/README.md Add your Stripe public key to the `.env.local` file to enable Stripe payment integration. Ensure the integration is also set up in your Medusa server. ```shell NEXT_PUBLIC_STRIPE_KEY= ``` -------------------------------- ### Fetch Paginated Products with Medusa Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Use `listProducts` for basic paginated product listings. `listProductsWithSort` fetches and sorts products client-side when backend sorting is not available. ```typescript import { listProducts, listProductsWithSort } from "@lib/data/products" // Basic paginated listing for a region: const { response, nextPage } = await listProducts({ pageParam: 1, countryCode: "us", queryParams: { limit: 12, collection_id: ["col_01JXYZ"], // fields are automatically expanded to include calculated prices }, }) // response.products → HttpTypes.StoreProduct[] // response.count → total number of matching products // nextPage → 2 (or null if no more pages) // Sorted listing (used on the /store page): const { response } = await listProductsWithSort({ page: 1, countryCode: "us", sortBy: "price_asc", // "price_asc" | "price_desc" | "created_at" queryParams: { limit: 12 }, }) // Fetches 100 products internally, sorts by minimum variant price, then slices for the requested page ``` -------------------------------- ### Product Listing Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Functions for fetching paginated products from the store API. `listProducts` is the low-level paginator, and `listProductsWithSort` fetches and applies client-side sorting. ```APIDOC ## Product Listing (`src/lib/data/products.ts`) Two functions for fetching paginated products from the store API. `listProducts` is the low-level paginator; `listProductsWithSort` fetches up to 100 products and applies client-side sorting (price ascending/descending, newest first) for when the backend doesn't support sort parameters. ```typescript import { listProducts, listProductsWithSort } from "@lib/data/products" // Basic paginated listing for a region: const { response, nextPage } = await listProducts({ pageParam: 1, countryCode: "us", queryParams: { limit: 12, collection_id: ["col_01JXYZ"], // fields are automatically expanded to include calculated prices }, }) // response.products → HttpTypes.StoreProduct[] // response.count → total number of matching products // nextPage → 2 (or null if no more pages) // Sorted listing (used on the /store page): const { response } = await listProductsWithSort({ page: 1, countryCode: "us", sortBy: "price_asc", // "price_asc" | "price_desc" | "created_at" queryParams: { limit: 12 }, }) // Fetches 100 products internally, sorts by minimum variant price, then slices for the requested page ``` ``` -------------------------------- ### Categories Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Functions for fetching the product category tree for navigation and category pages. ```APIDOC ## List Categories ### Description Fetches the complete product category tree, including children, products, and parent references. ### Method `listCategories` ### Parameters None ### Response Example ```json { "categories": "HttpTypes.StoreProductCategory[]" } ``` ## Get Category By Handle ### Description Resolves a nested category using URL segments and queries by its handle. Expands children and products. ### Method `getCategoryByHandle` ### Parameters - **handles** (string[]) - Required - An array of URL segments representing the category path (e.g., `["apparel", "mens", "shirts"]`). ### Response Example ```json { "category": "HttpTypes.StoreProductCategory (with category_children and products)" } ``` ``` -------------------------------- ### Fetch Product Collections Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Retrieve product collections for navigation and landing pages. Supports listing all collections, retrieving by ID, or by URL handle with expanded product details. Requires imports from '@lib/data/collections'. ```typescript import { listCollections, retrieveCollection, getCollectionByHandle, } from "@lib/data/collections" // List all collections (up to 100): const { collections, count } = await listCollections({ limit: "10" }) // → { collections: HttpTypes.StoreCollection[], count: number } // Retrieve a collection by ID: const collection = await retrieveCollection("col_01JXYZ") // → HttpTypes.StoreCollection // Retrieve a collection by URL handle (includes products): const collection = await getCollectionByHandle("summer-sale") // → HttpTypes.StoreCollection (with *products field expanded) ``` -------------------------------- ### Cart Management Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Server actions covering the full cart lifecycle: create-or-retrieve, add/update/remove items, apply promo codes, set shipping address, select a shipping method, initiate a payment session, and place the final order. ```APIDOC ## Cart Management (`src/lib/data/cart.ts`) Server actions covering the full cart lifecycle: create-or-retrieve, add/update/remove items, apply promo codes, set shipping address, select a shipping method, initiate a payment session, and place the final order. ```typescript import { retrieveCart, getOrSetCart, addToCart, updateLineItem, deleteLineItem, setShippingMethod, initiatePaymentSession, applyPromotions, setAddresses, placeOrder, updateRegion, listCartOptions, } from "@lib/data/cart" // Retrieve the current cart (uses _medusa_cart_id cookie): const cart = await retrieveCart() // → HttpTypes.StoreCart | null // Ensure a cart exists for a country (creates one if absent): const cart = await getOrSetCart("us") // Add a product variant: await addToCart({ variantId: "variant_01JXYZ", quantity: 2, countryCode: "us" }) // Update quantity of a line item: await updateLineItem({ lineId: "item_01JXYZ", quantity: 3 }) // Remove a line item: await deleteLineItem("item_01JXYZ") // Apply a promo code: await applyPromotions(["SUMMER20"]) // Also exposed as a form action: submitPromotionForm(currentState, formData) // Fetch available shipping options for the cart: const { shipping_options } = await listCartOptions() // Select a shipping method: await setShippingMethod({ cartId: "cart_01...", shippingMethodId: "so_01..." }) // Start a Stripe payment session: await initiatePaymentSession(cart, { provider_id: "pp_stripe_stripe" }) // Place the order — redirects to /{countryCode}/order/{id}/confirmed on success: await placeOrder() // Change region and revalidate caches: await updateRegion("de", "/store") ``` ``` -------------------------------- ### Fetch Product Category Tree Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Fetch the complete product category tree, including children, products, and parent references, or resolve a nested category using URL segments. Import functions from '@lib/data/categories'. ```typescript import { listCategories, getCategoryByHandle } from "@lib/data/categories" // Fetch the full category tree (children, products, parent refs): const categories = await listCategories() // → HttpTypes.StoreProductCategory[] // Each entry includes category_children, products, parent_category // Resolve a nested category from URL segments: const category = await getCategoryByHandle(["apparel", "mens", "shirts"]) // Joins segments as "apparel/mens/shirts" and queries by handle // → HttpTypes.StoreProductCategory (with category_children and products) ``` -------------------------------- ### Fetch and Manage Orders Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Retrieve a single order with full details, list paginated orders, or manage order transfer requests. Ensure necessary imports from '@lib/data/orders'. ```typescript import { retrieveOrder, listOrders, createTransferRequest, acceptTransferRequest, declineTransferRequest, } from "@lib/data/orders" // Retrieve a single order with full item + payment details: const order = await retrieveOrder("order_01JXYZ") // → HttpTypes.StoreOrder (includes items, variants, products, payments) // List paginated orders (newest first): const orders = await listOrders(10, 0) // → HttpTypes.StoreOrder[] // Request transfer of an order to another account (form action): const result = await createTransferRequest( { success: false, error: null, order: null }, formData // formData.get("order_id") ) // → { success: true, error: null, order: { id, email } } // Accept / decline a transfer token from an email link: await acceptTransferRequest("order_01JXYZ", "transfer-token-abc") await declineTransferRequest("order_01JXYZ", "transfer-token-abc") ``` -------------------------------- ### Retrieve Shipping Options and Calculate Prices Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt List available shipping options for a given cart or calculate the price for a specific shipping option, optionally including provider data. Use functions from '@lib/data/fulfillment'. ```typescript import { listCartShippingMethods, calculatePriceForShippingOption, } from "@lib/data/fulfillment" // List all shipping options for a cart: const shippingOptions = await listCartShippingMethods("cart_01JXYZ") // → HttpTypes.StoreShippingOption[] | null // Calculate the price for a specific shipping option: const option = await calculatePriceForShippingOption( "so_01JXYZ", // shipping option ID "cart_01JXYZ", // cart ID { custom_key: "value" } // optional provider data ) // → HttpTypes.StoreCartShippingOption | null ``` -------------------------------- ### Customer Authentication & Profile Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Server actions for customer registration, login/logout, cart transfer on auth, and address book CRUD. Authentication uses JWT tokens stored in a `_medusa_jwt` httpOnly cookie. ```APIDOC ## Customer Authentication & Profile (`src/lib/data/customer.ts`) Server actions for customer registration, login/logout, cart transfer on auth, and address book CRUD. Authentication uses JWT tokens stored in a `_medusa_jwt` httpOnly cookie. ```typescript import { retrieveCustomer, updateCustomer, signup, login, signout, transferCart, addCustomerAddress, updateCustomerAddress, deleteCustomerAddress, } from "@lib/data/customer" // Get the authenticated customer: const customer = await retrieveCustomer() // → HttpTypes.StoreCustomer | null (null when unauthenticated) // Register + auto-login (used as a form action): const result = await signup(undefined, formData) // formData fields: email, password, first_name, last_name, phone // Login (used as a form action): await login(undefined, formData) // formData fields: email, password // Automatically calls transferCart() to associate any guest cart // Logout — clears JWT and cart cookies, revalidates caches, redirects: await signout("us") // Transfer an anonymous cart to the logged-in customer: await transferCart() // Address book management: const { success, error } = await addCustomerAddress(currentState, formData) // formData fields: first_name, last_name, address_1, address_2, city, // postal_code, province, country_code, phone await updateCustomerAddress({ addressId: "addr_01..." }, formData) await deleteCustomerAddress("addr_01JXYZ") ``` ``` -------------------------------- ### Manage Cart Lifecycle with Medusa Server Actions Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Comprehensive server actions for cart operations including retrieval, item management, promotions, shipping, payment initiation, and order placement. Ensure a cart exists using `getOrSetCart` before performing other operations. ```typescript import { retrieveCart, getOrSetCart, addToCart, updateLineItem, deleteLineItem, setShippingMethod, initiatePaymentSession, applyPromotions, setAddresses, placeOrder, updateRegion, listCartOptions, } from "@lib/data/cart" // Retrieve the current cart (uses _medusa_cart_id cookie): const cart = await retrieveCart() // → HttpTypes.StoreCart | null // Ensure a cart exists for a country (creates one if absent): const cart = await getOrSetCart("us") // Add a product variant: await addToCart({ variantId: "variant_01JXYZ", quantity: 2, countryCode: "us" }) // Update quantity of a line item: await updateLineItem({ lineId: "item_01JXYZ", quantity: 3 }) // Remove a line item: await deleteLineItem("item_01JXYZ") // Apply a promo code: await applyPromotions(["SUMMER20"]) // Also exposed as a form action: submitPromotionForm(currentState, formData) // Fetch available shipping options for the cart: const { shipping_options } = await listCartOptions() // Select a shipping method: await setShippingMethod({ cartId: "cart_01...", shippingMethodId: "so_01..." }) // Start a Stripe payment session: await initiatePaymentSession(cart, { provider_id: "pp_stripe_stripe" }) // Place the order — redirects to /{countryCode}/order/{id}/confirmed on success: await placeOrder() // Change region and revalidate caches: await updateRegion("de", "/store") ``` -------------------------------- ### Collections Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Functions for fetching product collections, used for navigation and landing pages. ```APIDOC ## List Collections ### Description Lists all available product collections, with a default limit of 100. ### Method `listCollections` ### Parameters - **query** (object) - Optional - Query parameters for filtering and pagination. - **limit** (string) - Optional - The maximum number of collections to return. ### Response Example ```json { "collections": "HttpTypes.StoreCollection[]", "count": "number" } ``` ## Retrieve Collection ### Description Retrieves a single product collection by its ID. ### Method `retrieveCollection` ### Parameters - **id** (string) - Required - The ID of the collection to retrieve. ### Response Example ```json { "collection": "HttpTypes.StoreCollection" } ``` ## Get Collection By Handle ### Description Retrieves a product collection by its URL handle. This includes associated products. ### Method `getCollectionByHandle` ### Parameters - **handle** (string) - Required - The URL handle of the collection. ### Response Example ```json { "collection": "HttpTypes.StoreCollection (with *products field expanded)" } ``` ``` -------------------------------- ### Manage Customer Authentication and Profile Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Server actions for customer registration, login, logout, and profile management. Authentication relies on JWT tokens stored in an httpOnly cookie. Address book operations are also included. ```typescript import { retrieveCustomer, updateCustomer, signup, login, signout, transferCart, addCustomerAddress, updateCustomerAddress, deleteCustomerAddress, } from "@lib/data/customer" // Get the authenticated customer: const customer = await retrieveCustomer() // → HttpTypes.StoreCustomer | null (null when unauthenticated) // Register + auto-login (used as a form action): const result = await signup(undefined, formData) // formData fields: email, password, first_name, last_name, phone // Login (used as a form action): await login(undefined, formData) // formData fields: email, password // Automatically calls transferCart() to associate any guest cart // Logout — clears JWT and cart cookies, revalidates caches, redirects: await signout("us") // Transfer an anonymous cart to the logged-in customer: await transferCart() // Address book management: const { success, error } = await addCustomerAddress(currentState, formData) // formData fields: first_name, last_name, address_1, address_2, city, // postal_code, province, country_code, phone await updateCustomerAddress({ addressId: "addr_01..." }, formData) await deleteCustomerAddress("addr_01JXYZ") ``` -------------------------------- ### Fetch Configured Locales Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Retrieve a list of all locales configured on the Medusa backend, useful for building a locale switcher UI. Import `listLocales` from '@lib/data/locales'. Returns null if the endpoint is unavailable. ```typescript import { listLocales } from "@lib/data/locales" const locales = await listLocales() // → [{ code: "en", name: "English" }, { code: "de", name: "German" }] // Returns null if the /store/locales endpoint is not available (404) ``` -------------------------------- ### Manage User Locale Preference Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Handle user locale settings by reading from cookies, setting cookies directly, or performing a full update that also affects the active cart and caches. Use functions from '@lib/data/locale-actions'. ```typescript import { getLocale, setLocaleCookie, updateLocale } from "@lib/data/locale-actions" // Read the current locale from cookies: const locale = await getLocale() // → "en" | "de" | null // Set the locale cookie directly: await setLocaleCookie("fr") // Full update: sets cookie, updates the cart, and revalidates // products / categories / collections caches: const applied = await updateLocale("de") // → "de" ``` -------------------------------- ### Sort products client-side Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt The `sortProducts` utility allows for client-side sorting of product arrays based on price (ascending/descending) or creation date. ```typescript import { sortProducts } from "@lib/util/sort-products" const sorted = sortProducts(products, "price_asc") // Sorts by each product's minimum variant calculated_amount ascending const sortedDesc = sortProducts(products, "price_desc") const newest = sortProducts(products, "created_at") // Sorts by product.created_at descending (most recent first) ``` -------------------------------- ### Generate Array of Indices with `repeat` Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Use the `repeat` utility to generate an array of `n` indices, suitable for rendering skeleton loaders. Ensure the utility is imported correctly. ```typescript import repeat from "@lib/util/repeat" repeat(3).map((i) => ) // renders 3 skeleton cards ``` -------------------------------- ### Medusa Next.js Middleware for Region Detection Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Runs on the Next.js Edge runtime to detect and redirect requests based on country codes. Fetches store regions with a 1-hour cache and maps country codes to regions. Requires MEDUSA_BACKEND_URL, NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY, and NEXT_PUBLIC_DEFAULT_REGION environment variables. ```typescript // Automatic redirection example: // GET /products → 307 /{countryCode}/products // GET /us/products → passes through immediately // Environment variables required: // MEDUSA_BACKEND_URL=http://localhost:9000 // NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_... // NEXT_PUBLIC_DEFAULT_REGION=us (fallback when IP geolocation is unavailable) export const config = { matcher: [ "/((?!api|_next/static|_next/image|favicon.ico|images|assets|png|svg|jpg|jpeg|gif|webp).*)", ], } ``` -------------------------------- ### Payment provider constants and type guards Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Maps payment provider IDs to display information and provides helper functions (`isStripeLike`, `isPaypal`, `isManual`) to identify provider types. Also includes a list of currencies that do not require division by 100. ```typescript import { paymentInfoMap, isStripeLike, isPaypal, isManual, noDivisionCurrencies, } from "@lib/constants" // Display info for a provider: paymentInfoMap["pp_stripe_stripe"] // → { title: "Credit card", icon: } paymentInfoMap["pp_stripe-ideal_stripe"] // → { title: "iDeal", icon: } // Type guards: isStripeLike("pp_stripe_stripe") // true isStripeLike("pp_stripe-bancontact_stripe") // false (different prefix) isPaypal("pp_paypal_paypal") // true isManual("pp_system_default") // true // Currencies stored as whole numbers (no ÷100): noDivisionCurrencies.includes("jpy") // true noDivisionCurrencies.includes("usd") // false ``` -------------------------------- ### Medusa Cookie Utilities Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Server-only helpers for managing JWT auth, cart ID, and cache ID cookies. Provides 'getCacheOptions' for Next.js fetch cache tag revalidation. Includes functions for reading, writing, and clearing these cookies. ```typescript import { getAuthHeaders, getCacheOptions, getCacheTag, getCartId, setCartId, removeCartId, setAuthToken, removeAuthToken, } from "@lib/data/cookies" // Reading auth headers for any SDK call: const headers = await getAuthHeaders() // → { authorization: "Bearer " } or {} // Scoped cache tag for revalidation: const tag = await getCacheTag("carts") // → "carts-" // Next.js fetch cache options: const next = await getCacheOptions("products") // → { tags: ["products-"] } // Cart cookie lifecycle: const cartId = await getCartId() // read await setCartId("cart_01JXYZ...") // write (7-day httpOnly cookie) await removeCartId() // clear ``` -------------------------------- ### Check for Empty Values with `isEmpty` Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt The `isEmpty` utility function checks for null, undefined, empty objects, empty arrays, and blank strings. Import it from the specified path. ```typescript import { isEmpty } from "@lib/util/isEmpty" isEmpty(null) // true isEmpty({}) // true isEmpty([]) // true isEmpty(" ") // true isEmpty("hello") // false isEmpty({ a: 1 }) // false ``` -------------------------------- ### Fetch Product Variant with Images Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Retrieve a single product variant, including its associated images. Returns null if unauthenticated or an error occurs. Requires importing `retrieveVariant` from '@lib/data/variants'. ```typescript import { retrieveVariant } from "@lib/data/variants" const variant = await retrieveVariant("variant_01JXYZ") // → HttpTypes.StoreProductVariant (with *images expanded) | null // Returns null when unauthenticated or on error ``` -------------------------------- ### Fetch Payment Providers for a Region Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Retrieve a list of payment providers configured for a specific region. Requires importing `listCartPaymentMethods` from '@lib/data/payment'. ```typescript import { listCartPaymentMethods } from "@lib/data/payment" // Fetch payment providers for a region (sorted by ID): const providers = await listCartPaymentMethods("reg_01JXYZ") // → [ // { id: "pp_medusa-payments_default" }, // { id: "pp_stripe_stripe" }, // ... // ] | null ``` -------------------------------- ### Locales API Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Function for fetching the list of configured locales for a locale switcher UI. ```APIDOC ## List Locales ### Description Fetches the list of locales configured on the Medusa backend. ### Method `listLocales` ### Parameters None ### Response Example ```json [ { "code": "en", "name": "English" }, { "code": "de", "name": "German" } ] ``` ### Notes Returns `null` if the `/store/locales` endpoint is not available (e.g., returns a 404). ``` -------------------------------- ### Determine if a product is simple Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt The `isSimpleProduct` utility returns `true` if a product has only one option with a single value, indicating that variant selection UI can be skipped. ```typescript import { isSimpleProduct } from "@lib/util/product" isSimpleProduct(product) // true → render "Add to Cart" directly // false → render variant selector first ``` -------------------------------- ### Use `ModalProvider` and `useModal` for context-based modal closing Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Provides a `close` callback via React context to deeply nested components, avoiding prop drilling for modal dismissal. ```typescript import { ModalProvider, useModal } from "@lib/context/modal-context" // Wrap modal content with the provider: function Modal({ onClose, children }) { return ( {children} ) } // Consume close inside nested components without props: function ModalFooter() { const { close } = useModal() return } ``` -------------------------------- ### Compare addresses for equality Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt The `compareAddresses` utility checks if two address objects are identical based on key fields, useful for determining if a shipping address is the same as a billing address. ```typescript import compareAddresses from "@lib/util/compare-addresses" compareAddresses( { first_name: "Jane", last_name: "Doe", address_1: "123 Main St", city: "Berlin", country_code: "de", postal_code: "10115", province: "", phone: "", company: "" }, { first_name: "Jane", last_name: "Doe", address_1: "123 Main St", city: "Berlin", country_code: "de", postal_code: "10115", province: "", phone: "", company: "" } ) // → true ``` -------------------------------- ### Product Variant Retrieval Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Function for fetching a single product variant with its associated images. ```APIDOC ## Retrieve Variant ### Description Fetches a single product variant, including its images. ### Method `retrieveVariant` ### Parameters - **variantId** (string) - Required - The ID of the product variant to retrieve. ### Response Example ```json { "variant": "HttpTypes.StoreProductVariant (with *images expanded) | null" } ``` ### Notes Returns `null` when unauthenticated or on error. ``` -------------------------------- ### Locale Management Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Functions for managing the user's locale preference, including setting cookies and updating application state. ```APIDOC ## Get Locale ### Description Reads the current locale preference from cookies. ### Method `getLocale` ### Parameters None ### Response Example ```json "en" | "de" | null ``` ## Set Locale Cookie ### Description Sets the locale cookie directly. ### Method `setLocaleCookie` ### Parameters - **locale** (string) - Required - The locale code to set (e.g., "fr"). ## Update Locale ### Description Applies a locale change by setting the cookie, updating the cart, and revalidating relevant caches. ### Method `updateLocale` ### Parameters - **locale** (string) - Required - The locale code to apply (e.g., "de"). ### Response Example ```json "de" ``` ``` -------------------------------- ### Fulfillment Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Functions for retrieving shipping options and calculating shipping prices for a cart. ```APIDOC ## List Cart Shipping Methods ### Description Lists all available shipping options for a given cart. ### Method `listCartShippingMethods` ### Parameters - **cartId** (string) - Required - The ID of the cart. ### Response Example ```json { "shippingOptions": "HttpTypes.StoreShippingOption[] | null" } ``` ## Calculate Price For Shipping Option ### Description Calculates the price for a specific shipping option for a given cart, with optional provider data. ### Method `calculatePriceForShippingOption` ### Parameters - **shippingOptionId** (string) - Required - The ID of the shipping option. - **cartId** (string) - Required - The ID of the cart. - **providerData** (object) - Optional - Custom data for the shipping provider. ### Response Example ```json { "option": "HttpTypes.StoreCartShippingOption | null" } ``` ``` -------------------------------- ### Order Management Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Functions for retrieving and managing customer orders, including creating and responding to transfer requests. ```APIDOC ## Retrieve Order ### Description Retrieves a single order with full item, variant, product, and payment details. ### Method `retrieveOrder` ### Parameters - **orderId** (string) - Required - The ID of the order to retrieve. ### Response Example ```json { "order": "HttpTypes.StoreOrder" } ``` ## List Orders ### Description Lists paginated orders, sorted by newest first. ### Method `listOrders` ### Parameters - **limit** (number) - Optional - The maximum number of orders to return. - **offset** (number) - Optional - The number of orders to skip before returning results. ### Response Example ```json { "orders": "HttpTypes.StoreOrder[]" } ``` ## Create Transfer Request ### Description Requests a transfer of an order to another account. This is typically used in a form action. ### Method `createTransferRequest` ### Parameters - **formData** (FormData) - Required - Form data containing order details, including `order_id`. ### Response Example ```json { "success": true, "error": null, "order": { "id": "string", "email": "string" } } ``` ## Accept Transfer Request ### Description Accepts a transfer request using a transfer token. ### Method `acceptTransferRequest` ### Parameters - **orderId** (string) - Required - The ID of the order. - **transferToken** (string) - Required - The token associated with the transfer request. ## Decline Transfer Request ### Description Declines a transfer request using a transfer token. ### Method `declineTransferRequest` ### Parameters - **orderId** (string) - Required - The ID of the order. - **transferToken** (string) - Required - The token associated with the transfer request. ``` -------------------------------- ### Payment Providers Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Function for retrieving available payment providers for a region. ```APIDOC ## List Cart Payment Methods ### Description Fetches the payment providers available for a specific region, sorted by ID. ### Method `listCartPaymentMethods` ### Parameters - **regionId** (string) - Required - The ID of the region. ### Response Example ```json { "providers": [ { "id": "pp_medusa-payments_default" }, { "id": "pp_stripe_stripe" }, ... ] | null } ``` ``` -------------------------------- ### Use `useToggleState` hook for boolean state Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt A lightweight boolean state hook supporting object or array destructuring. Useful for managing UI states like modal visibility. ```typescript import useToggleState from "@lib/hooks/use-toggle-state" // Object destructuring: const { state, open, close, toggle } = useToggleState(false) // Array destructuring: const [isOpen, openModal, closeModal, toggleModal] = useToggleState() // Usage in a component: function AddressModal() { const { state: isOpen, open, close } = useToggleState() return ( <> {isOpen && ...} ) } ``` -------------------------------- ### Medusa Region Functions Source: https://context7.com/medusajs/nextjs-starter-medusa/llms.txt Provides functions to list all regions, retrieve a region by ID, or resolve a region from a country code. Caches region results in a module-level Map to optimize backend calls within a single render pass. ```typescript import { listRegions, retrieveRegion, getRegion } from "@lib/data/regions" // List all regions: const regions = await listRegions() // → [{ id: "reg_01...", name: "North America", countries: [...], currency_code: "usd" }] // Retrieve a single region by ID: const region = await retrieveRegion("reg_01JXYZ") // → { id: "reg_01JXYZ", currency_code: "usd", ... } // Resolve region from a country code (used in most pages): const region = await getRegion("us") // → { id: "reg_01JXYZ", currency_code: "usd", countries: [{ iso_2: "us", ... }] } // Returns null if the country code matches no region const unknownRegion = await getRegion("zz") // → null ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.