UNPKG

@techsio/storefront-data

Version:

Medusa-first storefront data layer built on TanStack Query.

210 lines (152 loc) • 5.97 kB
--- name: setup-storefront-platform-in-next-app description: > Load this skill when wiring @techsio/storefront-data into a Next.js App Router storefront through createMedusaStorefrontPreset, StorefrontDataProvider, createMedusaSdk, createLocalStorageValueStore, and explicit subpath imports. Use it for the app-level composition module, provider placement, browser storage seams, and avoiding package-root or ad-hoc preset wiring. type: framework library: "@techsio/storefront-data" framework: react library_version: "0.1.0" requires: [] sources: - "TechsioCZ/new-engine:libs/storefront-data/README.md" - "TechsioCZ/new-engine:libs/storefront-data/AGENTS.md" - "TechsioCZ/new-engine:libs/storefront-data/package.json" - "TechsioCZ/new-engine:libs/storefront-data/src/shared/medusa-client.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/shared/storage-value-store.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/shared/query-client.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/client/provider.tsx" - "TechsioCZ/new-engine:libs/storefront-data/src/medusa/preset.ts" --- # Setup storefront platform in Next app ## Setup Use one thin storefront composition module, one app-level provider boundary, and explicit file-level imports. ```js // next.config.mjs const nextConfig = { transpilePackages: ["@techsio/storefront-data"], } export default nextConfig ``` ```ts // src/lib/storefront.ts import { createMedusaSdk } from "@techsio/storefront-data/shared/medusa-client" import { createLocalStorageValueStore } from "@techsio/storefront-data/shared/storage-value-store" import { createMedusaStorefrontPreset } from "@techsio/storefront-data/medusa/preset" const sdk = createMedusaSdk({ baseUrl: process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL ?? "http://localhost:9000", publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY ?? "", }) const cartStorage = createLocalStorageValueStore({ key: "shop-cart-id", }) export const storefront = createMedusaStorefrontPreset({ sdk, queryKeyNamespace: "shop", cart: { hooks: { cartStorage, }, }, }) ``` ```tsx // app/providers.tsx "use client" import type { PropsWithChildren } from "react" import { StorefrontDataProvider } from "@techsio/storefront-data/client/provider" export function Providers({ children }: PropsWithChildren) { return <StorefrontDataProvider>{children}</StorefrontDataProvider> } ``` ## Hooks and Components ### Expose only the preset surface the app actually needs ```ts // src/lib/storefront-surface.ts import { storefront } from "@/src/lib/storefront" export const { auth, cart, catalog, checkout, collections, products, regions } = storefront.hooks export const { cart: cartFlow, checkout: checkoutFlow } = storefront.flows ``` Keep this layer thin. SDK config, local field defaults, address adapters, and storefront-specific policy belong here. Query keys, services, hooks, and flows stay owned by the preset. ### Pass a stable browser QueryClient only when the app really needs overrides ```tsx // app/providers.tsx "use client" import type { PropsWithChildren } from "react" import { StorefrontDataProvider } from "@techsio/storefront-data/client/provider" import { getQueryClient } from "@techsio/storefront-data/shared/query-client" const client = getQueryClient({ defaultOptions: { queries: { refetchOnWindowFocus: false, }, }, }) export function Providers({ children }: PropsWithChildren) { return <StorefrontDataProvider client={client}>{children}</StorefrontDataProvider> } ``` If the app does not need browser-client overrides, keep the provider as `<StorefrontDataProvider>{children}</StorefrontDataProvider>`. ## Common Mistakes ### CRITICAL Package-root imports Wrong: ```ts import { StorefrontDataProvider } from "@techsio/storefront-data" ``` Correct: ```ts import { StorefrontDataProvider } from "@techsio/storefront-data/client/provider" import { createMedusaStorefrontPreset } from "@techsio/storefront-data/medusa/preset" ``` The root export is intentionally disabled. Treat explicit subpaths as the supported public surface. Source: `libs/storefront-data/package.json`, `libs/storefront-data/README.md` ### HIGH Ad-hoc hook assembly instead of a preset Wrong: ```ts const products = createProductHooks({ service, queryKeyNamespace: "shop" }) const cart = createCartHooks({ service, queryKeyNamespace: "shop" }) ``` Correct: ```ts const storefront = createMedusaStorefrontPreset({ sdk, queryKeyNamespace: "shop", }) ``` The current architecture expects one preset to own hooks, services, query keys, cache semantics, and flow wrappers for a storefront. Source: `libs/storefront-data/README.md`, `libs/storefront-data/src/medusa/preset.ts` ### CRITICAL Server helpers inside client code Wrong: ```tsx "use client" import { getServerQueryClient } from "@techsio/storefront-data/server/get-query-client" ``` Correct: ```tsx "use client" import { StorefrontDataProvider } from "@techsio/storefront-data/client/provider" ``` `server/get-query-client` guards against client usage because its request-scoped behavior only makes sense on the server. Source: `libs/storefront-data/src/server/get-query-client.ts` ### HIGH Late provider config changes rebuild the browser client Wrong: ```tsx <StorefrontDataProvider clientConfig={{ defaultOptions: { queries: { staleTime: 0 } } }}> {children} </StorefrontDataProvider> ``` Correct: ```tsx const client = getQueryClient({ defaultOptions: { queries: { staleTime: 0 } }, }) <StorefrontDataProvider client={client}>{children}</StorefrontDataProvider> ``` The internal browser QueryClient is a singleton. Only the first internal initialization sees `clientConfig`. Source: `libs/storefront-data/src/client/provider.tsx`, `libs/storefront-data/src/shared/query-client.ts` See also: `implement-ssr-prefetch-and-query-client-boundaries` for server-side hydration and query-client ownership.