Skip to content

Commit 3cc360b

Browse files
fix incorrect logic in getCloudflareContext
1 parent b572baf commit 3cc360b

File tree

1 file changed

+43
-38
lines changed

1 file changed

+43
-38
lines changed

packages/cloudflare/src/api/cloudflare-context.ts

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -79,48 +79,53 @@ export function getCloudflareContext<
7979
// whether `getCloudflareContext` is run in "async mode"
8080
const asyncMode = options.async;
8181

82-
if (!cloudflareContext) {
83-
// The sync mode of `getCloudflareContext`, relies on the context being set on the global state
84-
// by either the worker entrypoint (in prod) or by `initOpenNextCloudflareForDev` (in dev), neither
85-
// can work during SSG since for SSG Next.js creates (jest) workers that don't get access to the
86-
// normal global state so we throw with a helpful error message.
87-
// Note: Next.js sets globalThis.__NEXT_DATA__.nextExport to true for SSG routes
88-
// source: https://github.com/vercel/next.js/blob/4e394608423/packages/next/src/export/worker.ts#L55-L57)
89-
if (!asyncMode && global.__NEXT_DATA__?.nextExport === true) {
90-
throw new Error(
91-
`\n\nERROR: \`getCloudflareContext\` has been called in a static route` +
92-
` that is not allowed, this can be solved in different ways:\n\n` +
93-
` - call \`getCloudflareContext({async: true})\` to use the \`async\` mode\n` +
94-
` - avoid calling \`getCloudflareContext\` in the route\n` +
95-
` - make the route non static\n`
96-
);
97-
}
98-
99-
if (asyncMode) {
100-
return getCloudflareContextFromWrangler<CfProperties, Context>().then((context) => {
101-
addCloudflareContextToNodejsGlobal(context);
102-
return context;
103-
});
104-
}
105-
106-
// the cloudflare context is initialized by the worker and is always present in production/preview
107-
// during local development (`next dev`) it might be missing only if the developers hasn't called
108-
// the `initOpenNextCloudflareForDev` function in their Next.js config file
82+
if (cloudflareContext) {
83+
return asyncMode ? Promise.resolve(cloudflareContext) : cloudflareContext;
84+
}
85+
86+
const inNodejsRuntime = process.env.NEXT_RUNTIME === "nodejs";
87+
88+
// Note: Next.js sets globalThis.__NEXT_DATA__.nextExport to true for SSG routes
89+
// source: https://github.com/vercel/next.js/blob/4e394608423/packages/next/src/export/worker.ts#L55-L57)
90+
const inSSG = global.__NEXT_DATA__?.nextExport === true;
91+
92+
if ((inNodejsRuntime || inSSG) && asyncMode) {
93+
// we're in a node.js process and also in "async mode" so we can use wrangler to asynchronously get the context
94+
return getCloudflareContextFromWrangler<CfProperties, Context>().then((context) => {
95+
addCloudflareContextToNodejsGlobal(context);
96+
return context;
97+
});
98+
}
99+
100+
// The sync mode of `getCloudflareContext`, relies on the context being set on the global state
101+
// by either the worker entrypoint (in prod) or by `initOpenNextCloudflareForDev` (in dev), neither
102+
// can work during SSG since for SSG Next.js creates (jest) workers that don't get access to the
103+
// normal global state so we throw with a helpful error message.
104+
if (inSSG) {
109105
throw new Error(
110-
`\n\nERROR: \`getCloudflareContext\` has been called without having called` +
111-
` \`initOpenNextCloudflareForDev\` from the Next.js config file.\n` +
112-
`You should update your Next.js config file as shown below:\n\n` +
113-
" ```\n // next.config.mjs\n\n" +
114-
` import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";\n\n` +
115-
` initOpenNextCloudflareForDev();\n\n` +
116-
" const nextConfig = { ... };\n" +
117-
" export default nextConfig;\n" +
118-
" ```\n" +
119-
"\n"
106+
`\n\nERROR: \`getCloudflareContext\` has been called in a static route,` +
107+
` that is not allowed, this can be solved in different ways:\n\n` +
108+
` - call \`getCloudflareContext({async: true})\` to use the \`async\` mode\n` +
109+
` - avoid calling \`getCloudflareContext\` in the route\n` +
110+
` - make the route non static\n`
120111
);
121112
}
122113

123-
return cloudflareContext;
114+
// the cloudflare context is initialized by the worker and is always present in production/preview
115+
// during local development (`next dev`) it might be missing only if the developers hasn't called
116+
// the `initOpenNextCloudflareForDev` function in their Next.js config file
117+
throw new Error(
118+
`\n\nERROR: \`getCloudflareContext\` has been called without having called` +
119+
` \`initOpenNextCloudflareForDev\` from the Next.js config file.\n` +
120+
`You should update your Next.js config file as shown below:\n\n` +
121+
" ```\n // next.config.mjs\n\n" +
122+
` import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";\n\n` +
123+
` initOpenNextCloudflareForDev();\n\n` +
124+
" const nextConfig = { ... };\n" +
125+
" export default nextConfig;\n" +
126+
" ```\n" +
127+
"\n"
128+
);
124129
}
125130

126131
/**

0 commit comments

Comments
 (0)