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 3bf0f5ada58c0..634355fff7440 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 @@ -2590,7 +2590,10 @@ If you haven't installed the Next.js Starter storefront in the first step, refer In `src/types/global.ts`, add the following types that you’ll use in your customizations: ```ts title="src/types/global.ts" -import { BaseProductVariant } from "@medusajs/framework/types/http/product/common" +import { + // other imports... + StoreProductVariant +} from "@medusajs/types" // ... @@ -2605,9 +2608,14 @@ export type DigitalProductMedia = { fileId: string type: "preview" | "main" mimeType: string + digitalProduct?: DigitalProduct[] +} + +export type DigitalProductPreview = DigitalProductMedia & { + url: string } -export type VariantWithDigitalProduct = BaseProductVariant & { +export type VariantWithDigitalProduct = StoreProductVariant & { digital_product?: DigitalProduct } @@ -2615,71 +2623,84 @@ export type VariantWithDigitalProduct = BaseProductVariant & { ### Retrieve Digital Products with Variants -To retrieve the digital products details when retrieving a product and its variants, in the `src/lib/data/products.ts` file, change the `getProductsById` and `getProductByHandle` functions to pass the digital products in the `fields` property passed to the `sdk.store.product.list` method: +To retrieve the digital products details when retrieving a product and its variants, in the `src/lib/data/products.ts` file, change the `listProducts` function to pass the digital products in the `fields` property passed to the `sdk.store.product.list` method: export const fieldHighlights = [ - ["12"], ["27"] + ["24"] ] ```ts title="src/lib/data/products.ts" highlights={fieldHighlights} -export const getProductsById = cache(async function ({ - ids, +export const listProducts = async ({ + pageParam = 1, + queryParams, + countryCode, regionId, }: { - ids: string[] - regionId: string -}) { - return sdk.store.product - .list( - { - // ... - fields: "*variants.calculated_price,*variants.digital_product", - } - // ... - ) - // ... -}) - -export const getProductByHandle = cache(async function ( - handle: string, - regionId: string -) { - return sdk.store.product - .list( + pageParam?: number + queryParams?: HttpTypes.FindParams & HttpTypes.StoreProductParams + countryCode?: string + regionId?: string +}): Promise<{ + response: { products: HttpTypes.StoreProduct[]; count: number } + nextPage: number | null + queryParams?: HttpTypes.FindParams & HttpTypes.StoreProductParams +}> => { + // ... + return sdk.client + .fetch<{ products: HttpTypes.StoreProduct[]; count: number }>( + `/store/products`, { // ... - fields: "*variants.calculated_price,*variants.digital_product", + query: { + // ... + fields: "*variants.calculated_price,+variants.inventory_quantity,+metadata,+tags,*variants.calculated_price,*variants.digital_product", + } } - // ... ) // ... -}) +} ``` When a customer views a product’s details page, digital products linked to variants are also retrieved. ### Get Digital Product Preview Links -To retrieve the links of a digital product’s preview media, add in `src/lib/data/products.ts` the following function: +To retrieve the links of a digital product’s preview media, first, add the following import at the top of `src/lib/data/products.ts`: ```ts title="src/lib/data/products.ts" -export const getDigitalProductPreview = cache(async function ({ +import { DigitalProductPreview } from "../../types/global" +``` + +Then, add the following function at the end of the file: + +```ts title="src/lib/data/products.ts" +export const getDigitalProductPreview = async function ({ id, }: { id: string }) { - 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()) + const headers = { + ...(await getAuthHeaders()), + } + + const next = { + ...(await getCacheOptions("products")), + } + const { previews } = await sdk.client.fetch<{ + previews: DigitalProductPreview[] + }>( + `/store/digital-products/${id}/preview`, + { + headers, + next, + cache: "force-cache" + } + ) // for simplicity, return only the first preview url // instead you can show all the preview media to the customer return previews.length ? previews[0].url : "" -}) +} ``` This function uses the API route you created in the previous section to get the preview links and return the first preview link. @@ -2776,17 +2797,25 @@ Start by creating the file `src/lib/data/digital-products.ts` with the following "use server" import { DigitalProduct } from "../../types/global" -import { getAuthHeaders } from "./cookies" +import { sdk } from "../config" +import { getAuthHeaders, getCacheOptions } from "./cookies" export const getCustomerDigitalProducts = async () => { - const { digital_products } = await fetch( - `${process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL}/store/customers/me/digital-products`, { - credentials: "include", - headers: { - ...getAuthHeaders(), - "x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY, - }, - }).then((res) => res.json()) + const headers = { + ...(await getAuthHeaders()), + } + + const next = { + ...(await getCacheOptions("products")), + } + const { digital_products } = await sdk.client.fetch<{ + digital_products: DigitalProduct[] + }>(`/store/customers/me/digital-products`, { + + headers, + next, + cache: "force-cache", + }) return digital_products as DigitalProduct[] } @@ -2801,7 +2830,6 @@ Then, create the file `src/modules/account/components/digital-products-list/inde import { Table } from "@medusajs/ui" import { DigitalProduct } from "../../../../types/global" -import { getDigitalMediaDownloadLink } from "../../../../lib/data/digital-products" type Props = { digitalProducts: DigitalProduct[] @@ -2847,9 +2875,7 @@ export const DigitalProductsList = ({ } ``` -This adds a `DigitalProductsList` component that receives a list of digital products and shows them in a table. - -Each digital product’s media has a download link. You’ll implement its functionality afterwards. +This adds a `DigitalProductsList` component that receives a list of digital products and shows them in a table. Each digital product’s media has a download link. You’ll implement its functionality afterwards. Next, create the file `src/app/[countryCode]/(main)/account/@dashboard/digital-products/page.tsx` with the following content: @@ -2902,26 +2928,44 @@ const AccountNav = ({ return (