Commerce integrations for deco.cx storefronts on TanStack Start + React 19 + Cloudflare Workers.
@decocms/apps provides VTEX, Shopify, and Resend integrations (loaders, actions, hooks, middleware) plus shared schema.org commerce types. It depends on @decocms/start.
π Read the full documentation β
npm install @decocms/appsA working VTEX storefront needs three things: a deco-vtex config block, an initVtexFromBlocks() call in setup, and the commerce loader registry.
{
"__resolveType": "deco-vtex",
"account": "my-store",
"publicUrl": "https://www.my-store.com.br",
"salesChannel": "1",
"appKey": { "__resolveType": "secret/key" },
"appToken": { "__resolveType": "secret/key" }
}import { createSiteSetup } from "@decocms/start/setup";
import { createInstrumentedFetch } from "@decocms/start/sdk/instrumentedFetch";
import { initVtexFromBlocks, setVtexFetch } from "@decocms/apps/vtex/client";
import { createVtexCommerceLoaders } from "@decocms/apps/vtex/commerceLoaders";
createSiteSetup({
sections: import.meta.glob("./sections/**/*.tsx", { eager: true }),
blocks,
meta: () => meta,
initPlatform: () => initVtexFromBlocks(),
getCommerceLoaders: () => createVtexCommerceLoaders(),
});
setVtexFetch(createInstrumentedFetch("vtex"));import { useCart, useUser, useWishlist } from "@decocms/apps/vtex/hooks";
function AddToCartButton({ sku }: { sku: string }) {
const { addItems, isMutating } = useCart();
return (
<button
onClick={() => addItems([{ id: sku, quantity: 1 }])}
disabled={isMutating}
>
Add to cart
</button>
);
}That's it. Loaders are auto-registered, hooks are typed, edge cache + cookie propagation work out of the box.
import { createSiteSetup } from "@decocms/start/setup";
import { initShopifyFromBlocks } from "@decocms/apps/shopify/client";
import { createShopifyCommerceLoaders } from "@decocms/apps/shopify/commerceLoaders";
createSiteSetup({
sections: import.meta.glob("./sections/**/*.tsx", { eager: true }),
blocks,
meta: () => meta,
initPlatform: () => initShopifyFromBlocks(),
getCommerceLoaders: () => createShopifyCommerceLoaders(),
});Config block (deco-shopify) needs storeName, storefrontAccessToken, languageCode, countryCode.
β οΈ Shopify cart loaders require cart-cookie wiring in your route handler. See Shopify reference for the canonical pattern.
import { initResendFromBlocks } from "@decocms/apps/resend/client";
import { sendEmail } from "@decocms/apps/resend/sdk";
await sendEmail({
to: "customer@example.com",
subject: "Order confirmed",
html: "<h1>Thanks!</h1>",
});| Subpath | Purpose |
|---|---|
@decocms/apps/vtex |
Barrel index |
@decocms/apps/vtex/client |
vtexFetch, vtexFetchWithCookies, intelligentSearch, setVtexFetch, initVtexFromBlocks, configureVtex |
@decocms/apps/vtex/commerceLoaders |
createVtexCommerceLoaders |
@decocms/apps/vtex/loaders/* |
Cart, user, wishlist, search, catalog, sessions, orders, autocomplete |
@decocms/apps/vtex/actions/* |
Cart mutations, auth, profile, address, wishlist, newsletter |
@decocms/apps/vtex/hooks |
useCart, useUser, useWishlist, useAutocomplete, plus createUseCart / createUseUser / createUseWishlist factories |
@decocms/apps/vtex/inline-loaders/* |
PDP, PLP, shelves, suggestions, minicart |
@decocms/apps/vtex/middleware |
extractVtexContext, vtexCacheKeySuffix, propagateISCookies, createVtexCheckoutProxy |
@decocms/apps/vtex/utils/* |
Transform, segment, cookies, slugCache, sortwhitelist |
π‘ Calling VTEX loaders/actions from the client. Use the typed
invokeclient generated by@decocms/startβinvoke["vtex/loaders/cart.ts"](props)β or use the React hooks above. There is no@decocms/apps/vtex/invokesubpath.
| Subpath | Purpose |
|---|---|
@decocms/apps/shopify |
Barrel |
@decocms/apps/shopify/client |
setShopifyFetch, GraphQL helpers |
@decocms/apps/shopify/loaders/* |
PDP, PLP, ProductList, RelatedProducts, Cart, Account |
@decocms/apps/shopify/actions/cart/* |
addItems, updateItems, discountCodesUpdate |
@decocms/apps/shopify/actions/user/* |
signIn, signUp |
@decocms/apps/shopify/utils/* |
Transform, cookies, GraphQL queries |
| Subpath | Purpose |
|---|---|
@decocms/apps/resend/client |
initResendFromBlocks |
@decocms/apps/resend/sdk |
sendEmail |
@decocms/apps/resend/actions/send |
Invocable email action |
Platform-agnostic types and components.
| Subpath | Purpose |
|---|---|
@decocms/apps/commerce/types |
schema.org Product, ProductDetailsPage, ProductListingPage, Offer, BreadcrumbList, etc. |
@decocms/apps/commerce/components/Image |
Optimized commerce image with CDN routing |
@decocms/apps/commerce/components/Picture |
<picture> with responsive sources |
@decocms/apps/commerce/components/JsonLd |
Structured data for SEO |
@decocms/apps/commerce/sdk/useOffer |
Pick the best offer per region/seller |
@decocms/apps/commerce/sdk/format |
formatPrice, formatPriceRange |
@decocms/apps/commerce/sdk/analytics |
Event types + mapProductToAnalyticsItem |
@decocms/apps/commerce/sdk/useVariantPossibilities |
Variant axis builder for selectors |
| Subpath | Purpose |
|---|---|
@decocms/apps/website |
configureWebsite, configureSeo |
@decocms/apps/website/loaders/redirectsFromCsv |
Bulk redirects from CSV |
@decocms/apps/website/loaders/fonts/* |
Google fonts, custom CDN font loaders |
Complete export tables: docs.deco.cx/v2/en/reference/commerce-exports.
The commerce documentation lives at docs.deco.cx/v2/en/commerce:
- VTEX overview β config block, secrets, install steps.
- VTEX loaders & actions β input/output cookbook.
- VTEX hooks β
useCart,useUser,useWishlist,useAutocomplete. - VTEX gotchas β cookies, sales channel, regionId, IS sort sanitization.
- Shopify β configure, loaders, actions, cart-cookie wiring.
- Resend β email setup.
{
"@decocms/start": ">=2.0.0",
"@tanstack/react-query": ">=5.0.0",
"react": ">=19.0.0",
"react-dom": ">=19.0.0"
}The published peer floor is React 18 to ease incremental migration, but the v2 stack assumes React 19 + the React Compiler.
npm run typecheck # tsc --noEmit
npm run check # typecheck + unused export detectionThis is a library β there is no dev server. Consumer storefronts run their own vite dev.
MIT