diff --git a/.changeset/brave-pandas-add.md b/.changeset/brave-pandas-add.md new file mode 100644 index 00000000..9aa690f8 --- /dev/null +++ b/.changeset/brave-pandas-add.md @@ -0,0 +1,10 @@ +--- +"@opennextjs/cloudflare": patch +--- + +fix: provide a proper error message when using `getCloudflareContext` in static routes + +`getCloudflareContext` can't be used in static routes, currently a misleading error +message incorrectly tells the developer that they haven't called `initOpenNextCloudflareForDev` +in their config file, this change updates such error message to properly clarify what +the issue is (and how to solve it) diff --git a/packages/cloudflare/src/api/cloudflare-context.ts b/packages/cloudflare/src/api/cloudflare-context.ts index 27e63651..55a19191 100644 --- a/packages/cloudflare/src/api/cloudflare-context.ts +++ b/packages/cloudflare/src/api/cloudflare-context.ts @@ -35,14 +35,14 @@ export type CloudflareContext< const cloudflareContextSymbol = Symbol.for("__cloudflare-context__"); /** - * `globalThis` override for internal usage (simply the standard `globalThis`) enhanced with - * a property indexed by the `cloudflareContextSymbol` + * `globalThis` override for internal usage */ type InternalGlobalThis< CfProperties extends Record = IncomingRequestCfProperties, Context = ExecutionContext, > = typeof globalThis & { [cloudflareContextSymbol]: CloudflareContext | undefined; + __NEXT_DATA__: Record; }; /** @@ -59,6 +59,20 @@ export function getCloudflareContext< const cloudflareContext = global[cloudflareContextSymbol]; if (!cloudflareContext) { + // For SSG Next.js creates (jest) workers that run in parallel, those don't get the current global + // state so they can't get access to the cloudflare context, unfortunately there isn't anything we + // can do about this, so the only solution is to error asking the developer to opt-out of SSG + // Next.js sets globalThis.__NEXT_DATA__.nextExport to true for the worker, so we can use that to detect + // that the route is being SSG'd (source: https://github.com/vercel/next.js/blob/4e394608423/packages/next/src/export/worker.ts#L55-L57) + if (global.__NEXT_DATA__?.nextExport === true) { + throw new Error( + `\n\nERROR: \`getCloudflareContext\` has been called in a static route` + + ` that is not allowed, please either avoid calling \`getCloudflareContext\`` + + ` in the route or make the route non static (for example by exporting the` + + ` \`dynamic\` route segment config set to \`'force-dynamic'\`.\n` + ); + } + // the cloudflare context is initialized by the worker and is always present in production/preview // during local development (`next dev`) it might be missing only if the developers hasn't called // the `initOpenNextCloudflareForDev` function in their Next.js config file