Storefront
Commerce enginePreviewTome storefront layer — a cookie-token shopping cart (guest and member, merged at sign-in, swept on a TTL), a single store-facts global, a public non-leaky stock-availability projection, a product listing that joins catalog, prices and availability, and cookie-aware Next.js server actions. Money stays in economy, stock in fulfillment, product nouns in catalog.
Get a registry token from your credentials page. You need a purchase that includes this package, or a Craft Library membership.
Add the registry and your token to the
.npmrcat the root of your project, with your token in place ofYOUR_TOKEN:@wabbit:registry=https://npm.wabbit.com/ //npm.wabbit.com/:_authToken=YOUR_TOKENThen install:
npm install @wabbit/tome-storefront
Overview
@wabbit/tome-storefront
The neutral layer that turns Tome's commerce primitives into a working shop for physical goods. It owns the shopper's cart, one store-facts source, a public derived-availability read and the browse listing. It does not own money, stock or product data: money stays in @wabbit/tome-economy, stock in @wabbit/tome-fulfillment, product nouns in @wabbit/tome-catalog.
This is increment S1, "storefront core, no money". It ships the storefront-carts collection with an opaque-cookie token, the storefront-settings global, the guest-to-member cart merge, a daily cart sweep, the public availability projection and endpoint, the product listing and the cookie-aware Next.js wrappers. It does not ship checkout, order views, restock alerts or any block; those arrive in later increments (the money path needs economy's multi-line checkout action first).
Installation
pnpm add @wabbit/tome-storefront| Peer | Range | Optional? | |---|---|---| | @wabbit/tome-core | >=1.23.0 <2.0.0 | no — access helpers, the layer registry, capabilities, the GDPR registry, the jobs adapters and the shared unstable_cache loader. | | @wabbit/tome-catalog | >=1.5.0 <2.0.0 | no — products and variants the cart and listing read (turn variants on with createCatalogLayer({ variants: true })). | | @wabbit/tome-economy | >=0.14.0 <1.0.0 | no — prices the cart re-reads on every display, and the payment adapter type. | | @wabbit/tome-fulfillment | >=0.2.0 <1.0.0 | no — stock rows behind the availability read, and the flat-rate shipping seam. | | @wabbit/tome-local | >=0.2.0 <1.0.0 | yes — when installed, the dispatch line falls back to the business profile's timezone if the store settings set none. | | payload | >=3.67.0 | no — the collection, global, endpoint and job task are Payload config. | | next | >=15.0.0 | yes — ./next reads next/headers, and the settings save hook revalidates through next/cache. |
server-only is a runtime dependency, imported by ./server alone.
Module surface
| Entry | Safe in a client bundle | What it carries | |---|---|---| | @wabbit/tome-storefront | no (Payload config) | createStorefrontLayer, the carts collection and settings global factories, cartSweepHandler, config helpers, constants and every public type | | @wabbit/tome-storefront/server | no (server-only) | the cart operations (getCart, addToCart, updateCartLine, removeCartLine, setShipCountry, clearCart, getPricedCart), getStorefrontAvailability, listStorefrontProducts, getStoreFacts, getStorefrontSettings, the cart-cookie helpers | | @wabbit/tome-storefront/next | no (reads next/headers) | createStorefrontActions and createStorefrontRouteHandlers, the cookie-aware wrappers over the server API |
Server/client posture: nothing here renders UI, so no entry is imported by a client component. Code that runs inside Payload (hooks, jobs, the CLI) imports the file it needs, because the server-only guard throws outside a React Server Components build.
Setting up
import { createStorefrontLayer } from '@wabbit/tome-storefront'
import { createStripeAdapter } from '@wabbit/tome-economy'
const storefront = createStorefrontLayer({
adapter: () => createStripeAdapter({ secretKey: process.env.STRIPE_SECRET_KEY! }),
publicBaseUrl: process.env.NEXT_PUBLIC_SERVER_URL!,
tokenSecret: process.env.STOREFRONT_TOKEN_SECRET!, // must differ from PAYLOAD_SECRET
})
export default buildConfig({
// ...
plugins: [storefront.plugin], // or spread storefront.collections / globals / endpoints, not both
})adapter, publicBaseUrl and tokenSecret are required. Cart defaults are 50 lines, quantity 99 and a 30-day (guest) or 90-day (member) TTL; the cart cookie is tome_cart. jobs: false registers no task, and the consumer runs the cart sweep itself. The layer reserves the storefront- collection prefix.
Behaviour to know
- The cart holds identities, never prices: a line is
(product, variantSku, quantity), and every display re-reads the active one-time price. - The browser holds only a random token in an httpOnly, SameSite=Lax cookie (Secure in production); the row stores its SHA-256 hash. Carts are admin-only over REST and GraphQL and are registered with the GDPR registry.
- Availability is a public, non-leaky projection (
in-stock,lowwith the remaining count at or under the threshold,out,untracked). It never exposesonHandorreserved. storefront-settingsis the single source for currency, shipping rates, the free-shipping threshold, the minimum order, dispatch and returns copy. Thestorefront:edit-settingscapability is granted toadminandeditor.
Exports
@wabbit/tome-storefront@wabbit/tome-storefront/server@wabbit/tome-storefront/next
Changelog
f3ef493: New package: `@wabbit/tome-storefront`, the cart, store-facts and availability layer for physical goods (increment S1, no money path). - **`createStorefrontLayer`:** returns the `storefront-carts` collection, the `storefront-settings` global, the public availability endpoint and the `storefront-cart-sweep` task, plus a `plugin` that appends all four. `adapter`, `publicBaseUrl` and `tokenSecret` are required; cart limits default to 50 lines, quantity 99 and a 30-day guest or 90-day member TTL. `jobs: false` registers no task. - **`./server`:** cart operations resolved from an opaque cookie token (stored as a SHA-256 hash), the guest-to-member merge at sign-in, a re-priced cart, the public availability projection (`in-stock`, `low`, `out`, `untracked`, never raw counts), the browse listing and the cached store facts. - **`./next`:** cookie-aware server actions and route handlers over the server API. Not in this release: checkout, order confirmation and lookup, restock alerts, and the storefront blocks.
- f3ef493: New package: `@wabbit/tome-storefront`, the cart, store-facts and availability layer for physical goods (increment S1, no money path). - **`createStorefrontLayer`:** returns the `storefront-carts` collection, the `storefront-settings` global, the public availability endpoint and the `storefront-cart-sweep` task, plus a `plugin` that appends all four. `adapter`, `publicBaseUrl` and `tokenSecret` are required; cart limits default to 50 lines, quantity 99 and a 30-day guest or 90-day member TTL. `jobs: false` registers no task. - **`./server`:** cart operations resolved from an opaque cookie token (stored as a SHA-256 hash), the guest-to-member merge at sign-in, a re-priced cart, the public availability projection (`in-stock`, `low`, `out`, `untracked`, never raw counts), the browse listing and the cached store facts. - **`./next`:** cookie-aware server actions and route handlers over the server API. Not in this release: checkout, order confirmation and lookup, restock alerts, and the storefront blocks.