UNPKG

@techsio/storefront-data

Version:

Medusa-first storefront data layer built on TanStack Query.

236 lines (182 loc) • 5.97 kB
--- name: configure-pagination-prefetch-and-cache-policy description: > Load this skill when tuning @techsio/storefront-data cacheConfig, skipIfCached, skipMode, usePrefetchProducts, usePrefetchCatalogProducts, or usePrefetchPages. Use it for pagination, page planning, normalized query inputs, and keeping prefetch behavior aligned with shared query keys and cache strategy rules. type: core library: "@techsio/storefront-data" library_version: "0.1.0" requires: - setup-storefront-platform-in-next-app sources: - "TechsioCZ/new-engine:libs/storefront-data/README.md" - "TechsioCZ/new-engine:libs/storefront-data/src/shared/cache-config.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/shared/prefetch.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/shared/prefetch-pages-plan.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/shared/query-keys.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/products/hooks.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/catalog/hooks.ts" - "TechsioCZ/new-engine:libs/storefront-data/tests/shared.prefetch-pages-plan.test.ts" - "TechsioCZ/new-engine:libs/storefront-data/tests/regression.shared-orders-customers.test.tsx" --- # Configure pagination, prefetch, and cache policy ## Setup Use the preset to set cache strategy defaults, then use the shared prefetch helpers instead of app-local loops or hand-written query keys. ```ts // src/lib/storefront.ts import { createCacheConfig } from "@techsio/storefront-data/shared/cache-config" import { createMedusaSdk } from "@techsio/storefront-data/shared/medusa-client" 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 ?? "", }) export const storefront = createMedusaStorefrontPreset({ sdk, queryKeyNamespace: "shop", cacheConfig: createCacheConfig({ semiStatic: { staleTime: 30 * 60 * 1000, }, }), }) ``` ## Core Patterns ### Use hook-owned prefetch helpers instead of app-local `queryClient.prefetchQuery` ```tsx "use client" import { storefront } from "@/src/lib/storefront" export function ProductCardPrefetch() { const { prefetchProduct } = storefront.hooks.products.usePrefetchProduct({ skipIfCached: true, skipMode: "any", }) return ( <button type="button" onMouseEnter={() => prefetchProduct({ handle: "classic-tee", region_id: "reg_123", country_code: "cz", }) } > Hover to prefetch </button> ) } ``` ### Use the shared page planner for list pagination prefetch ```tsx "use client" import { storefront } from "@/src/lib/storefront" export function ListingPrefetch({ regionId, countryCode, currentPage, totalPages, }: { regionId: string countryCode: string currentPage: number totalPages: number }) { storefront.hooks.products.usePrefetchPages({ baseInput: { region_id: regionId, country_code: countryCode, limit: 24, }, currentPage, totalPages, hasNextPage: currentPage < totalPages, hasPrevPage: currentPage > 1, pageSize: 24, }) return null } ``` ### Use query-option helpers for manual reads and SSR ```ts import { storefront } from "@/src/lib/storefront" const listOptions = storefront.hooks.products.getListQueryOptions({ region_id: "reg_123", country_code: "cz", limit: 24, }) ``` Treat `getListQueryOptions` and `getDetailQueryOptions` as the canonical source of query keys and query functions whenever you leave the hook path. ## Common Mistakes ### CRITICAL Hand-written query keys or query options Wrong: ```ts const queryKey = ["shop", "products", params] useQuery({ queryKey, queryFn }) ``` Correct: ```ts const options = storefront.hooks.products.getListQueryOptions(params) useQuery(options) ``` Manual keys drift from normalized key builders and break cache identity across hooks, SSR prefetch, and cart cache sync. Source: `libs/storefront-data/src/shared/query-keys.ts`, `libs/storefront-data/tests/regression.shared-orders-customers.test.tsx` ### HIGH Reading `skipIfCached` as any-hit semantics Wrong: ```ts const { prefetchProducts } = storefront.hooks.products.usePrefetchProducts({ skipIfCached: true, }) ``` Correct: ```ts const { prefetchProducts } = storefront.hooks.products.usePrefetchProducts({ skipIfCached: true, skipMode: "any", }) ``` The default skip mode is `"fresh"`. Stale data still refetches unless you explicitly choose `"any"`. Source: `libs/storefront-data/src/shared/prefetch.ts`, `libs/storefront-data/src/products/hooks.ts` ### HIGH Non-plain values in normalized query inputs Wrong: ```ts storefront.hooks.products.useProducts({ filters: new URLSearchParams(location.search), trace: () => console.log("debug"), }) ``` Correct: ```ts storefront.hooks.products.useProducts({ q: search, category_id: categoryIds, }) ``` The query-key normalizer expects plain serializable structures and only strips known control flags like `enabled`. Source: `libs/storefront-data/src/shared/query-keys.ts` ### MEDIUM App-local pagination loops Wrong: ```ts for (let page = 1; page <= 3; page++) { await prefetchPage(page) } ``` Correct: ```tsx storefront.hooks.products.usePrefetchPages({ baseInput, currentPage, totalPages, hasNextPage, hasPrevPage, pageSize: 24, }) ``` The shared page planner encodes the platform's tested expectations for immediate and delayed prefetch order. Source: `libs/storefront-data/src/shared/prefetch-pages-plan.ts`, `libs/storefront-data/tests/shared.prefetch-pages-plan.test.ts` ## References - [Prefetch and pagination reference](references/prefetch-and-pagination.md) See also: `implement-ssr-prefetch-and-query-client-boundaries` for Server Component prefetch and hydration.