diff --git a/.changeset/fix-vite-dev-miniflare-zone.md b/.changeset/fix-vite-dev-miniflare-zone.md new file mode 100644 index 0000000000..38efdb29b8 --- /dev/null +++ b/.changeset/fix-vite-dev-miniflare-zone.md @@ -0,0 +1,9 @@ +--- +"wrangler": patch +--- + +Pass the local dev zone through `unstable_getMiniflareWorkerOptions` + +When `@cloudflare/vite-plugin` asks Wrangler for Miniflare worker options, the returned object did not include the inferred `zone`. Miniflare then fell back to `.example.com` for the `CF-Worker` header, which differs from the `wrangler dev --local` path and can cause some upstreams to reject local subrequests. + +This now forwards the same `dev.host` or inferred route host that Wrangler already uses in local dev so Vite-backed local development matches the existing local runtime behavior. diff --git a/packages/wrangler/src/__tests__/unstable-get-miniflare-worker-options.test.ts b/packages/wrangler/src/__tests__/unstable-get-miniflare-worker-options.test.ts new file mode 100644 index 0000000000..cde1b1416b --- /dev/null +++ b/packages/wrangler/src/__tests__/unstable-get-miniflare-worker-options.test.ts @@ -0,0 +1,61 @@ +import { describe, it } from "vitest"; +import { unstable_getMiniflareWorkerOptions } from "../api"; +import type { Config } from "@cloudflare/workers-utils"; + +function makeConfig( + overrides: Partial<{ + dev: { host?: string; enable_containers?: boolean; container_engine?: string }; + route: string; + routes: string[]; + }> = {} +): Config { + return { + name: "test-worker", + main: "./src/index.ts", + compatibility_date: "2025-06-17", + compatibility_flags: [], + rules: [], + queues: { producers: [], consumers: [] }, + migrations: [], + tail_consumers: undefined, + streaming_tail_consumers: undefined, + containers: [], + assets: undefined, + define: {}, + bindings: [], + compliance_region: undefined, + dev: { + ip: "localhost", + port: undefined, + local_protocol: "http", + upstream_protocol: "http", + enable_containers: false, + ...overrides.dev, + }, + ...overrides, + } as unknown as Config; +} + +describe("unstable_getMiniflareWorkerOptions", () => { + it("forwards dev.host as the Miniflare zone", ({ expect }) => { + const { workerOptions } = unstable_getMiniflareWorkerOptions( + makeConfig({ + dev: { host: "example.workers.dev" }, + }) + ); + + expect(workerOptions.zone).toBe("example.workers.dev"); + }); + + it("infers the Miniflare zone from the first route when dev.host is unset", ({ + expect, + }) => { + const { workerOptions } = unstable_getMiniflareWorkerOptions( + makeConfig({ + routes: ["https://subdomain.example.com/*"], + }) + ); + + expect(workerOptions.zone).toBe("subdomain.example.com"); + }); +}); diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index 364d882d5d..cb2ad126ec 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -9,7 +9,7 @@ import { getAssetsOptions } from "../../../assets"; import { readConfig } from "../../../config"; import { partitionDurableObjectBindings } from "../../../deployment-bundle/entry"; import { DEFAULT_MODULE_RULES } from "../../../deployment-bundle/rules"; -import { getBindings } from "../../../dev"; +import { getBindings, getInferredHost } from "../../../dev"; import { getDurableObjectClassNameToUseSQLiteMap } from "../../../dev/class-names-sqlite"; import { buildAssetOptions, @@ -349,6 +349,17 @@ export interface Unstable_MiniflareWorkerOptions { externalWorkers: WorkerOptions[]; } +function getMiniflareZone(config: Config): string | undefined { + if (config.dev.host) { + return config.dev.host; + } + + return getInferredHost( + (config.route && [config.route]) || config.routes, + config.configPath + ); +} + export function unstable_getMiniflareWorkerOptions( configPath: string, env?: string, @@ -461,6 +472,7 @@ export function unstable_getMiniflareWorkerOptions( compatibilityDate: config.compatibility_date, compatibilityFlags: config.compatibility_flags, modulesRules, + zone: getMiniflareZone(config), containerEngine: useContainers ? (config.dev.container_engine ?? resolveDockerHost(getDockerPath())) : undefined,