Deco
Pt

Worker entry

createDecoWorkerEntry — a camada mais externa do seu Cloudflare Worker.

createDecoWorkerEntry é a camada mais externa de uma loja v2. Embrulha o server entry do TanStack Start e roda rotas de admin, cache e bypass de assets estáticos antes do framework receber o request.

Import

 import { createDecoWorkerEntry } from "@decocms/start/sdk/workerEntry"; 

Uso mínimo

 // src/worker-entry.ts
import "./setup";   // TEM que ser primeiro

import { createDecoWorkerEntry } from "@decocms/start/sdk/workerEntry";
import {
  handleMeta,
  handleDecofile,
  handleRender,
  handleInvoke,
} from "@decocms/start/admin";
import serverEntry from "./server";

const decoWorker = createDecoWorkerEntry(serverEntry, {
  admin: {
    handleMeta,
    handleDecofile,
    handleRender,
    handleInvoke,
  },
});

export default decoWorker; 

Esse é o worker entry mais enxuto pronto para produção.

import "./setup" precisa vir primeiro. O setup registra sections, loaders e matchers em estado de escopo de módulo. Se o split de server-fn do TanStack acontecer antes do setup rodar, partes do registro ficam vazias em produção. Sempre coloque import "./setup"; no topo de src/server.ts E de src/worker-entry.ts .

Fluxo de request

 Request → createDecoWorkerEntry()
  ├─ tryAdminRoute()        → /live/_meta, /.decofile, /live/previews/*
  ├─ check de purge         → __deco_purge_cache=1
  ├─ bypass de assets       → /assets/*, favicon.ico, sprite.svg
  ├─ edge cache Cloudflare  → caches.open() com TTLs por profile
  └─ serverEntry.fetch()    → TanStack Start cuida do resto 

Os passos são curto-circuito: rota de admin retorna direto sem tocar o framework; HIT no cache retorna sem rodar o server entry.

Opções

 type WorkerEntryOptions = {
  admin?: {
    handleMeta: AdminHandler;
    handleDecofile: AdminHandler;
    handleRender: AdminHandler;
    handleInvoke: AdminHandler;
  };
  proxyHandler?: (request: Request, env: Env) => Promise<Response | null>;
  buildSegment?: (request: Request) => Record<string, string>;
  productionOrigins?: string[];
  cachePurgeKey?: string;
}; 

admin

Passe os quatro handlers de admin de @decocms/start/admin . Sem eles o admin não conversa com a sua loja.

Se quiser estender (auth custom, regras CORS), embrulhe os handlers:

 const handleMetaWithAuth: AdminHandler = async (request, env) => {
  if (!isAuthorized(request)) return new Response("Unauthorized", { status: 401 });
  return handleMeta(request, env);
}; 

proxyHandler

Roda depois das rotas de admin e do check de cache, mas antes do server entry. Usado para proxies do site (checkout do commerce, encaminhamento de URLs legadas).

Um uso comum é o proxy de checkout VTEX:

 import { createVtexCheckoutProxy } from "@decocms/apps/vtex/middleware";

const proxyHandler = createVtexCheckoutProxy({
  checkoutOrigin: "https://www.example.com.br",
  htmlTransform: (html) => html.replace(/<script>/g, "<script defer>"),
});

const decoWorker = createDecoWorkerEntry(serverEntry, {
  admin: {/* ... */},
  proxyHandler,
}); 

Outro uso comum é redirects legados carregados de um arquivo CSV — veja Carregamento de redirects abaixo.

buildSegment

Devolve um objeto chave-valor que entra na cache key. Usado para segmentar cache por região, device ou estado do usuário.

 import { detectDevice } from "@decocms/start/sdk/useDevice";

const decoWorker = createDecoWorkerEntry(serverEntry, {
  admin: {/* ... */},
  buildSegment: (request) => ({
    device: detectDevice(request).type,        // mobile / tablet / desktop
    country: request.headers.get("cf-ipcountry") ?? "?",
  }),
}); 

O framework anexa o segmento à cache key, então segmentos diferentes pegam respostas cacheadas diferentes.

productionOrigins

Whitelist das origens com as quais o admin pode falar. Default: origem do admin em produção, mais localhost em dev.

cachePurgeKey

Secret para o endpoint de purge. Quando ?__deco_purge_cache=<key> está presente, o framework invalida as entradas relevantes. Em produção, use uma string aleatória forte.

Wrapper de A/B

Para A/B no nível de versão do site (canary, experimentos full-stack), embrulhe o worker em withABTesting :

 import { withABTesting } from "@decocms/start/sdk/abTesting";

export default withABTesting(decoWorker, {
  kvBinding: "SITES_KV",
  preHandler: (request, url) => {
    return null;
  },
}); 

Veja A/B testing e redirects.

Carregamento de redirects

@decocms/start/sdk/redirects expõe loadRedirects(blocks) que encontra redirects definidos pelo CMS em .deco/blocks/ e produz um matcher chamável do proxyHandler :

 import { loadBlocks } from "@decocms/start/cms";
import { loadRedirects, matchRedirect } from "@decocms/start/sdk/redirects";

const cmsRedirects = loadRedirects(loadBlocks());

const proxyHandler = (request: Request, url: URL) => {
  const redirect = matchRedirect(url.pathname, cmsRedirects);
  if (redirect) {
    const target = url.search ? `${redirect.to}${url.search}` : redirect.to;
    return new Response(null, { status: redirect.status, headers: { Location: target } });
  }
  return null;
}; 

Para sites com milhares de redirects legados vindos de uma URL scheme da era Fresh, o mesmo slot proxyHandler aceita lógica de lookup arbitrária. Faça bundle de um CSV via import csv from "./redirects.csv?raw" , parse uma vez no escopo do módulo e bata contra url.pathname .

Tratamento de assets estáticos

Assets estáticos ( /assets/* , /favicon.ico , /sprite.svg ) passam direto. O Worker lê do diretório de assets bundled e devolve com cache headers apropriados. Você não configura — é automático.

Integração com cache

createDecoWorkerEntry chama caches.default direto. A cache key é a URL mais o segmento de buildSegment . TTLs vêm dos profiles de URL via @decocms/start/sdk/cacheHeaders .

Cache API ignora s-maxage . O framework escreve max-age (browser) e armazena entradas pelo equivalente a s-maxage . É um workaround para um detalhe da Cache API do Cloudflare.

Por que os handlers de admin moram nessa camada

Você verá esse aviso duas vezes: é importante.

O Vite remove lógica custom de createServerEntry em builds de produção. Se você botar /live/_meta dentro de server.ts , funciona em dev e some em prod. Sempre conecte admin via worker-entry.ts .

O framework deliberadamente separa server entry (TanStack-owned) de worker entry (loja-owned) por essa razão.

Veja também

Found an error or want to improve this page?

Edit this page