1---
2title: Worker Previews
3description: Deploy a branch or pull request as a first-class Preview of another Worker — its own URL, bindings, and isolated Durable Object state, without touching production traffic.
4sidebar:
5 order: 2
6---
7
8A [Worker Preview](https://developers.cloudflare.com/workers/previews/) is
9a named copy of a Worker: own URL, own variables, secrets, and
10bindings, and isolated same-Worker Durable Object (and Container)
11state. The parent's live deployment is untouched.
12
13This is the branch and pull-request path. It is **not** a Worker
14version. Versions are for gradual rollouts and canaries — see
15[Gradual deployments](/cloudflare/compute/gradual-deployments).
16
17## Preview another stage's Worker
18
19```typescript
20const parent = yield* Cloudflare.Worker.ref("Api", { stage: "prod" });
21
22const api = yield* Cloudflare.Worker("Api", {
23 main: "./src/api.ts",
24 preview: {
25 of: parent,
26 message: `PR #${process.env.PR_NUMBER}`,
27 },
28});
29
30// https://<stage>-<worker>.<account>.workers.dev
31api.url;
32```
33
34The Preview name defaults to a DNS-safe form of the stack stage
35(`pr-123`, `feat-login`). Override with `preview.name`. Destroying
36the Preview Worker deletes the Preview; the parent stays up.
37
38Bindings are whatever *this* Worker declares. Point them at staging
39resources, or let a PR stage create its own KV / D1 / R2. Same-Worker
40[Durable Object](/cloudflare/compute/durable-objects) classes are
41isolated automatically — each Preview gets its own namespace, deleted
42with the Preview. Version workers (`version.parent`) cannot host
43Durable Object classes; Previews can.
44
45## Custom-domain Preview URLs
46
47Enable Previews on the **parent** Worker's custom domain:
48
49```typescript
50yield* Cloudflare.Worker("Api", {
51 main: "./src/api.ts",
52 domain: {
53 name: "app.example.com",
54 previews: true,
55 },
56});
57```
58
59A Preview of that Worker is then at
60`https://<preview-name>.app.example.com`, plus a pinned
61`https://<deployment-id>-<preview-name>.app.example.com` per deploy.
62
63Use a dedicated Preview hostname (`previews.example.com`) when
64production already has subdomains, so the wildcard does not collide
65with `docs.example.com`.
66
67## Preview, version, or stage?
68
69| What you want | Use |
70|---|---|
71| Branch / PR with its own URL and isolated DOs | `preview.of` |
72| Canary a percentage of live traffic | `version.parent` + `version.traffic` |
73| Gradual rollout of this Worker | `version.traffic` |
74| Inspect one upload without routing | `version.traffic: 0` |
75| Persistent env, or infra that must be fully isolated (new table, matching service bindings) | A separate Alchemy **stage** |
76
77`preview` and `version.parent` cannot be set together.
78
79Service bindings from a Preview currently resolve to the bound
80Worker's **production** deployment. Crons, queue consumers, and
81production routes stay on production. For an end-to-end multi-Worker
82PR, deploy a full stage instead.
83
84Preview URLs are public. Protect them with
85[Cloudflare Access](/cloudflare/security/access) on the parent
86Worker (`access.previews` stays on by default).