Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/brave-pandas-add.md
Original file line number Diff line number Diff line change
@@ -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)
18 changes: 16 additions & 2 deletions packages/cloudflare/src/api/cloudflare-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, unknown> = IncomingRequestCfProperties,
Context = ExecutionContext,
> = typeof globalThis & {
[cloudflareContextSymbol]: CloudflareContext<CfProperties, Context> | undefined;
__NEXT_DATA__: Record<string, unknown>;
};

/**
Expand All @@ -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
Expand Down