Skip to main content

ce-ssr-patterns

SSR/meta-framework patterns for Commerce Engine using @commercengine/storefront. Covers Next.js, TanStack Start, Astro, and SvelteKit with publicStorefront(), clientStorefront(), serverStorefront(), bootstrap, server functions/actions, pre-rendering, and cookie-based token management.

Source facts

Repository
commercengine/skills
Last source activity
August 22, 2026 at 08:06
Detected SKILL.md language
English
Stars
0
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
8 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
ce-ssr-patterns
description
SSR/meta-framework patterns for Commerce Engine using @commercengine/storefront. Covers Next.js, TanStack Start, Astro, and SvelteKit with publicStorefront(), clientStorefront(), serverStorefront(), bootstrap, server functions/actions, pre-rendering, and cookie-based token management.
license
MIT
allowed-tools
Bash
metadata
{"author":"commercengine","version":"2.0.0"}
> **LLM Docs Header**: All requests to `https://llm-docs.commercengine.io` **must** include the `Accept: text/markdown` header (or append `.md` to the URL path). Without it, responses return HTML instead of parseable markdown. # SSR / Meta-Framework Patterns For basic installation, see `setup/`. For the rarer case where you need custom request-bound SSR bindings with `@commercengine/ssr-utils` (Nuxt or other unsupported frameworks), see `ssr/`. This skill covers frameworks with **first-party Commerce Engine wrappers**: Next.js, TanStack Start, Astro, and SvelteKit. All ship as subpath exports of `@commercengine/storefront`. ## Impact Levels - **CRITICAL** - Session continuity bugs, auth bugs - **HIGH** - Common mistakes - **MEDIUM** - Performance or maintainability issues ## References | Reference | When to Use | |-----------|-------------| | `references/nextjs.md` | CRITICAL - Next.js setup, accessor rules, Server Actions, SSG | | `references/tanstack-start.md` | CRITICAL - TanStack Start setup, server functions, route loaders, pre-rendering | | `references/astro.md` | CRITICAL - Astro setup, browser bootstrap, server-only cookie access | | `references/sveltekit.md` | CRITICAL - SvelteKit setup, load functions, hooks, form actions | | `references/token-management.md` | HIGH - Token flow, bootstrap pattern, cookie configuration | ## Shared Mental Model All first-party SSR wrappers follow the same three-accessor pattern (Next.js, TanStack Start, Astro, SvelteKit): | Accessor | Environment | Purpose | |----------|-------------|---------| | `publicStorefront()` | Server or client | Build-safe public reads (catalog, categories, store config). API-key-backed, no session. | | `clientStorefront()` | Client only | Browser-side session client. Throws if called on server. | | `serverStorefront()` | Server only | Request-bound session with cookie-backed token storage. Next.js: `await storefront.serverStorefront()`. TanStack Start: `serverStorefront()` from server-only module. Astro: `serverStorefront(Astro.cookies)`. SvelteKit: `serverStorefront(cookies)` in load/hooks/actions. | ### Bootstrap SSR apps **must** call `storefront.bootstrap()` on the client (root layout mount) before later `serverStorefront()` reads depend on cookie continuity. Without it, session continuity is not guaranteed. See each framework's reference for the exact bootstrap pattern. ### Pre-rendering for SEO & Initial Load Use `publicStorefront()` in route loaders (TanStack Start) or `generateStaticParams` / Server Components (Next.js) to pre-render catalog pages. This gives you excellent SEO and fast initial page loads: ```typescript // Route loader (TanStack Start) or Server Component (Next.js) const sdk = storefront.publicStorefront(); const { data } = await sdk.catalog.listProducts({ limit: 100 }); ``` `publicStorefront()` never creates sessions, never reads/writes cookies, and is safe for build-time, pre-render, and ISR contexts. ### Client-Side Fetching After Hydration Once the app is hydrated, **client-side fetching is equally fast and much less complex**. There is no need to wrap SDK calls in server functions — the SDK talks to a public API with no secrets to protect. Use React Query (or any fetching library) directly: ```typescript // Public reads — no session needed const sdk = storefront.publicStorefront(); const { data } = await sdk.catalog.listProducts({ limit: 20 }); // Session-bound reads (cart, wishlist, account) — use client accessor const sessionSdk = storefront.clientStorefront(); const { data: wishlist } = await sessionSdk.cart.getWishlist(); ``` The session-aware overloads resolve `user_id` automatically — no manual ID passing needed. ## Framework Quick Reference | Framework | Import | Factory | Server Entry | Server Accessor | Env Prefix | Reference | |-----------|--------|---------|-------------|-----------------|------------|-----------| | Next.js | `.../nextjs` | `createNextjsStorefront()` | Built-in (async) | `await storefront.serverStorefront()` | `NEXT_PUBLIC_` | `references/nextjs.md` | | TanStack Start | `.../tanstack-start` | `createTanStackStartStorefront()` | `.../tanstack-start/server` | `serverStorefront()` | `VITE_` | `references/tanstack-start.md` | | Astro | `.../astro` | `createAstroStorefront()` | `.../astro/server` | `serverStorefront(Astro.cookies)` | `PUBLIC_` | `references/astro.md` | | SvelteKit | `.../sveltekit` | `createSvelteKitStorefront()` | `.../sveltekit/server` | `serverStorefront(cookies)` | `PUBLIC_` | `references/sveltekit.md` | All imports above are subpaths of `@commercengine/storefront`. See the framework-specific reference for full setup, accessor rules, patterns, and examples. ## Hosted Checkout + SSR When using Hosted Checkout with an SSR framework, the Storefront SDK remains the session owner. Wire `onTokensUpdated` in the storefront config so checkout stays in sync on the client side: ```typescript // In storefront config (both frameworks) onTokensUpdated: (accessToken, refreshToken) => { if (typeof window !== "undefined") { void import("@commercengine/checkout").then(({ getCheckout }) => { getCheckout().updateTokens(accessToken, refreshToken); }); } }, ``` Then initialize checkout in the bootstrap/initializer component after `storefront.bootstrap()` completes. No provider wrapper needed — `initCheckout` is called once and `useCheckout()` works globally. > **Callback signature difference:** The SDK's `onTokensUpdated` receives two separate arguments `(accessToken, refreshToken)`. Checkout's `onTokensUpdated` receives a single object `({ accessToken, refreshToken })`. Do not mix these up. ```tsx useEffect(() => { const init = async () => { await storefront.bootstrap(); const sdk = storefront.clientStorefront(); const accessToken = await sdk.getAccessToken(); const refreshToken = await sdk.session.peekRefreshToken(); initCheckout({ storeId: /* ... */, apiKey: /* ... */, authMode: "provided", accessToken: accessToken ?? undefined, refreshToken: refreshToken ?? undefined, onTokensUpdated: ({ accessToken, refreshToken }) => { void sdk.setTokens(accessToken, refreshToken); }, }); }; void init(); return () => destroyCheckout(); }, []); ``` ## Common Pitfalls (All SSR Frameworks) | Level | Issue | Solution | |-------|-------|----------| | CRITICAL | Using `publicStorefront()` for cart, auth, customer, order, or payment flows | Use the session accessor (`serverStorefront()` on server, `clientStorefront()` on client) | | CRITICAL | Using `clientStorefront()` on the server | Use the server accessor — `clientStorefront()` throws on the server | | HIGH | Missing bootstrap component in root layout | Mount a client component calling `storefront.bootstrap()` once in the root layout | | HIGH | Bootstrapping anonymous auth in SSG/pre-render code | Use `publicStorefront()` instead — pre-render code must not create sessions | | MEDIUM | Fetching session-aware data in the root layout | Move it into a request-aware boundary and use the server accessor | ## See Also - `setup/` - Basic SDK installation and framework detection - `ssr/` - Custom SSR bindings with `@commercengine/ssr-utils` (Nuxt and other unsupported frameworks) - `auth/` - Authentication flows - `cart-checkout/` - Cart and Hosted Checkout patterns ## Documentation - **SDK Documentation**: https://www.commercengine.io/docs/sdk - **LLM Reference**: https://llm-docs.commercengine.io/sdk/
View on GitHub