Shopify
Configure Shopify for a Blocks 7.x storefront and wire server-side products, carts, and customers.
@decocms/apps-shopify connects a released Blocks 7.x website to Shopify's Storefront API. It supplies server-side loaders and actions. Your storefront owns its React UI and server functions; the Site Editor edits the saved app configuration.
Configuration
Block
Set the Shopify subdomain and public storefront URL:
{
"__resolveType": "deco-shopify",
"storeName": "my-shop",
"publicUrl": "https://my-shop.example.com"
}Store SHOPIFY_STOREFRONT_TOKEN in the server environment. On Workers, set it with wrangler secret put SHOPIFY_STOREFRONT_TOKEN. Autoconfiguration resolves the environment fallback when no token is saved; it also supports the integration's encrypted-secret format. Keep secrets out of ordinary public content fields.
Wiring
After framework setup loads the decofile, run this server-only module:
import { autoconfigApps, type AppRegistry } from "@decocms/blocks-admin/apps";
import { loadBlocks } from "@decocms/blocks/cms";
import { SHOPIFY_REGISTRY_ENTRY } from "@decocms/apps-shopify/registry";
import * as shopifyMod from "@decocms/apps-shopify/mod";
const APP_REGISTRY: AppRegistry = [
{ ...SHOPIFY_REGISTRY_ENTRY, module: async () => shopifyMod },
];
await autoconfigApps(loadBlocks(), APP_REGISTRY);There is no default combined registry. Pass the blocks map and the registry explicitly. initShopifyFromBlocks(blocks) is a convenience alternative that accepts a plain-text token and configures once per process; it does not decrypt a secret object or read the token environment fallback. Use the registry path above for those cases.
Client
Enable instrumented fetch once in server setup:
import { setShopifyFetch, createShopifyFetch } from "@decocms/apps-shopify";
setShopifyFetch(createShopifyFetch());The package pins the Storefront API version in its client. It has no provider response cache; wrap read loaders with the framework's cached-loader helper when needed.
Loaders
Call the exported functions with the actual page URL:
import { productDetailsPageLoader, productListingPageLoader } from "@decocms/apps-shopify";
const url = new URL("https://my-shop.example.com/collections/summer");
const product = await productDetailsPageLoader({ slug: "blue-widget" }, url);
const listing = await productListingPageLoader({ collectionName: "summer", count: 24 }, url);ProductListingPage handles collection and search results; there is no separate SearchPage loader. Content can refer to registered loaders such as shopify/loaders/ProductDetailsPage and shopify/loaders/ProductListingPage. For CMS resolution, use the URL wrapper when query parameters and product links need the real request URL.
Cart cookie
The cart loader is getCart from @decocms/apps-shopify/loaders/cart. It reads the cookie from request headers; when response headers are provided, it can create a cart and write its cookie. Forward those response headers to the browser.
Creating a cookie does not mutate the incoming request headers. Before adding items on that same request, the action must receive headers containing the newly created cart ID. Follow the complete cart and customer workflow.
Actions
Cart actions are exported by @decocms/apps-shopify/actions/cart; customer actions live under actions/user/. They require the request/response headers their signatures specify. Use the exact 7.x action names and inputs, rather than old actions/customer/login or loaders/Account keys.
Hooks
The package does not ship Shopify React hooks or request middleware. Build your UI around server functions owned by the storefront. Generated invoke bindings are for registered handlers; a made-up shopify/loaders/Cart.ts key is not a cart endpoint.
Utils
Use the exported commerce types and Shopify transform utilities described in the framework integration guide. The public API is the package's exported surface.
Differences from VTEX
Shopify uses Storefront GraphQL and its own cart/customer cookies. VTEX's middleware, region handling, and hooks do not transfer to Shopify. Framework-level caching and observability are separate from the provider client.
Open issues
Features depend on the installed integration version. Check the 7.x contract before adding a custom hook or action, and validate product, search, cart, and customer flows against your store.