UNPKG

@techsio/storefront-data

Version:

Medusa-first storefront data layer built on TanStack Query.

234 lines (179 loc) • 5.53 kB
--- name: implement-auth-and-customer-session-flows description: > Load this skill when using @techsio/storefront-data for customer auth and session state through storefront.hooks.auth.useAuth, useLogin, useRegister, useLogout, and invalidateOnAuthChange. Use it for login/register flows, session-aware rendering, cross-domain invalidation, and app-level callbacks for toasts, analytics, or redirects. 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/src/auth/hooks.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/auth/medusa-service.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/auth/query-keys.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/medusa/preset.ts" - "TechsioCZ/new-engine:libs/storefront-data/tests/auth.medusa-service.test.ts" --- ## Setup Let the preset own the auth service and invalidation. Keep UX side effects in the app. ```ts // src/lib/storefront.ts 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", auth: { hooks: { invalidateOnAuthChange: { includeDefaults: true, }, }, }, }) ``` ## Core Patterns ### Gate account UI through `useAuth` ```tsx "use client" import { storefront } from "@/src/lib/storefront" export function AccountGate() { const auth = storefront.hooks.auth.useAuth() if (auth.isLoading) return <div>Loading...</div> if (!auth.isAuthenticated) return <div>Please sign in</div> return <div>{auth.customer?.email}</div> } ``` ### Keep UX side effects in app callbacks ```tsx "use client" import { storefront } from "@/src/lib/storefront" import { toast } from "sonner" const track = (event: string) => { console.log(event) } export function LoginButton() { const login = storefront.hooks.auth.useLogin({ onSuccess: () => { toast.success("Logged in") }, }) return ( <button type="button" onClick={() => login.mutate({ email: "alice@example.com", password: "secret" })} > Log in </button> ) } ``` ### Recover registration edge cases through the shared register hook ```tsx "use client" import { storefront } from "@/src/lib/storefront" export function RegisterButton() { const register = storefront.hooks.auth.useRegister() return ( <button type="button" onClick={() => register.mutate({ email: "alice@example.com", password: "secret", first_name: "Alice", last_name: "Example", }) } > Register </button> ) } ``` The shared auth service already handles the Medusa-specific recovery and cleanup semantics. The app should only add storefront policy around it. ## Common Mistakes ### HIGH Rebuilding auth in the app Wrong: ```ts const register = async (input: RegisterInput) => { await sdk.auth.register("customer", "emailpass", input) await sdk.auth.login("customer", "emailpass", input) } ``` Correct: ```ts const register = storefront.hooks.auth.useRegister() register.mutate(input) ``` Local auth re-implementation reintroduces the exact cleanup and invalidation bugs that the shared auth surface is meant to absorb. Source: `libs/storefront-data/src/auth/medusa-service.ts`, `libs/storefront-data/src/auth/hooks.ts` ### CRITICAL Assuming multi-step auth is already supported Wrong: ```ts storefront.hooks.auth.useLogin().mutate({ provider: "google" }) ``` Correct: ```ts storefront.hooks.auth.useLogin().mutate({ email: "alice@example.com", password: "secret", }) ``` The current Medusa auth adapter rejects multi-step flows. The obvious generic-provider shape is misleading here. Source: `libs/storefront-data/src/auth/medusa-service.ts`, `libs/storefront-data/tests/auth.medusa-service.test.ts` ### HIGH Putting UX callbacks into shared auth code Wrong: ```ts const storefront = createMedusaStorefrontPreset({ sdk, auth: { hooks: { onSuccess: () => toast.success("Logged in"), }, }, }) ``` Correct: ```ts const login = storefront.hooks.auth.useLogin({ onSuccess: () => { toast.success("Logged in") track("login_success") }, }) ``` Toasts, redirects, analytics, and debug behavior belong in the app layer, not inside the shared auth contract. Source: `libs/storefront-data/src/auth/hooks.ts`, maintainer interview ### HIGH Forgetting cross-domain invalidation needs Wrong: ```ts const storefront = createMedusaStorefrontPreset({ sdk, auth: { hooks: { invalidateOnAuthChange: { includeDefaults: false } } }, }) ``` Correct: ```ts const storefront = createMedusaStorefrontPreset({ sdk, auth: { hooks: { invalidateOnAuthChange: { includeDefaults: true, }, }, }, }) ``` Auth changes usually affect customer and order data. If you turn off default invalidation, do it intentionally and replace it with equivalent app-specific rules. Source: `libs/storefront-data/src/medusa/preset.ts`, `libs/storefront-data/src/auth/hooks.ts` See also: `decide-app-specific-overrides-vs-shared-platform` for thin wrapper rules.