Ir para o conteúdo
decodecodeveloper docs
Storefront → Blocks → Apps

Wake

Connect a site to Wake Commerce for catalog pages, search, carts, wishlists and checkout routing.

Esta página ainda não foi traduzida para o português — o conteúdo abaixo está em inglês.

@decocms/apps-wake connects a site to Wake Commerce through its Storefront GraphQL API and checkout REST API. It provides cached catalog loaders (product pages, listings, shelves, search suggestions, recommendations, shop info and partners), per-visitor loaders for the cart, user and wishlist, and actions for the cart, coupons, kits, wishlists, newsletters, reviews, notify-me and shipping simulation. Everything returns the shared commerce types.

bun add @decocms/apps-wake @decocms/apps-commerce @decocms/apps-website

Configuring

Wake keeps its credentials out of content. The block holds only where to connect; the token always comes from the environment:

Block fieldWhat it does
accountRequired. Your Wake account name.
checkoutUrlYour checkout and login domain, such as https://secure.store.example.com. Defaults to https://<account>.checkout.fbits.store.
storefrontEndpointOptional. The Storefront API endpoint; defaults to Wake's public one.
VariableWhat it does
WAKE_TOKENRequired. The Storefront API token.
WAKE_KEYThe admin API token. Read, but not used by any loader or action yet.

The app reads both from process.env only, not from the Worker's per-request environment. On Cloudflare Workers, process.env is available only with the nodejs_compat compatibility flag, so check that WAKE_TOKEN is visible there: if it isn't, configure returns null and the app silently isn't installed.

Install it with the registry entry; its block key is deco-wake. configure returns null, and the app isn't installed, when the block has no account or WAKE_TOKEN isn't set:

src/setup/apps.ts
import { autoconfigApps, type AppRegistry } from "@decocms/blocks-admin/apps";
import { loadBlocks } from "@decocms/blocks/cms";
import { WAKE_REGISTRY_ENTRY } from "@decocms/apps-wake/registry";
import * as wakeMod from "@decocms/apps-wake/mod";
 
const APP_REGISTRY: AppRegistry = [{ ...WAKE_REGISTRY_ENTRY, module: async () => wakeMod }];
 
await autoconfigApps(loadBlocks(), APP_REGISTRY);

Or configure it by hand: initWakeFromBlocks(blocks) reads the wake or deco-wake block, and configureWake(config) takes the config directly. Both are exported from the package root.

Instrumented fetch

Call setWakeFetch(createWakeFetch()) once, at module scope in your setup:

src/setup.ts
import { setWakeFetch, createWakeFetch } from "@decocms/apps-wake";
 
setWakeFetch(createWakeFetch());

Each call is then measured and traced, named after its GraphQL operation or checkout endpoint. Without it, calls use a plain fetch with a timeout and aren't measured. See Observability.

Cached catalog loaders

createWakeCommerceLoaders() returns the catalog loaders wrapped in the framework's loader cache, ready for registerCommerceLoaders:

src/setup/commerce-loaders.ts
import { registerCommerceLoaders } from "@decocms/blocks/cms";
import { createWakeCommerceLoaders } from "@decocms/apps-wake/commerceLoaders";
 
registerCommerceLoaders(createWakeCommerceLoaders());
KeyCache profileNotes
wake/loaders/productDetailsPage.tsproductUses the page path when slug is empty. Reads ?skuId to pick the variant.
wake/loaders/productListingPage.tslistingUses the current page URL for paging, sorting and filters.
wake/loaders/productList.tslistingShelves, with filters by category, brand, attributes, price and stock.
wake/loaders/suggestion.tssearchAutocomplete.
wake/loaders/recommendations.tsproductRecommendations for a product.
wake/loaders/shop.ts, wake/loaders/partners.tsstaticShop info and partners.

Each key is also registered without .ts. Override profiles with cacheProfiles and add loaders with extra, as with VTEX. The cart, user and wishlist loaders are deliberately left out: they're per visitor and never cached.

The listing loader reads Wake's URL conventions: busca for the search term, sort or ordenacao for sorting (SALES:DESC by default), page for the page number, tamanho for the page size, and filtro and precoPor for filters. Its props include limit (12), sort, query, onlyMainVariant (true), filters and pageOffset (0 or 1, 0 by default).

Cart, user and wishlist

Session state lives in Wake's cookies:

CookieHolds
carrinho-idThe cart id. Readable by browser scripts, so client code can reuse it.
fbits-loginThe login, exchanged with Wake's checkout for a customer token.
partner-tokenThe active partner, when partner pricing applies. HttpOnly.

The cart, user and wishlist loaders and every action read these from the current request through request context, and write Set-Cookie headers to the request's response headers, which invoke copies onto its response. That's why calling them through /deco/invoke needs no extra wiring. The cart loader creates a cart when the visitor has none; cart actions fail with Missing cart cookie (HTTP 400) until one exists.

The actions, at @decocms/apps-wake/actions/... and as wake/actions/... invoke keys:

ActionProps
cart/addItem, cart/addItemsproductVariantId, quantity, optional customization and subscription (a list under products for addItems)
cart/updateItemQuantityproductVariantId, quantity
cart/addCoupon, cart/removeCouponcoupon
cart/addKit, cart/removeKitproducts, quantity, kitId
cart/partnerAssociate, cart/partnerDisassociatepartnerAccessToken
wishlist/addProduct, wishlist/removeProductproductId
newsletter/registeremail, name
review/createemail, name, productVariantId, rating, review
notifymeemail, name, productVariantId
shippingSimulationcep, plus either productVariantId and quantity for one product, or simulateCartItems to quote the visitor's cart; useSelectedAddress uses the address already on the cart
submmitFormbody, recaptchaToken (the module name really is spelled this way)

The package doesn't ship React hooks. Call these through your own server functions or /deco/invoke.

Checkout routes and the sitemap

Wake's checkout, login, cart and account pages are served by Wake. To keep them on your domain, your Worker forwards those paths to the checkout URL.

@decocms/apps-wake/loaders/proxy returns the list of routes to forward, as plain descriptors: /checkout, /Fechamento and /Fechamento/*, /Login, /Login/*, /login/* and /Login/Authenticate, /Carrinho/*, /api/*, /MinhaConta and /MinhaConta/*, any extraPathsToProxy you pass, and a sitemap route for /Sitemap.xml. Each proxy descriptor carries the target in url (your checkout URL). It doesn't proxy anything itself: your Worker's proxyHandler does the forwarding.

@decocms/apps-wake/handlers/sitemap serves Wake's sitemap for your account with your host in every URL; pass include to add entries to it.

src/worker-entry.ts (excerpt)
import proxyRoutes from "@decocms/apps-wake/loaders/proxy";
import Sitemap from "@decocms/apps-wake/handlers/sitemap";
 
function matches(template: string, pathname: string) {
  return template.endsWith("/*")
    ? pathname.startsWith(template.slice(0, -1))
    : pathname === template;
}
 
export default createDecoWorkerEntry(serverEntry, {
  proxyHandler: async (request, url) => {
    if (url.pathname === "/Sitemap.xml") return Sitemap()(request);
    for (const route of proxyRoutes({})) {
      if (route.type === "proxy" && matches(route.pathTemplate, url.pathname)) {
        return fetch(new Request(new URL(url.pathname + url.search, route.url), request));
      }
    }
    return null;
  },
});
This sketch forwards requests as they are. A production proxy also has to rewrite the Domain of the checkout's Set-Cookie headers and its Location redirects to your host, the way VTEX's checkout proxy does.