···11+---
22+"@opennextjs/cloudflare": minor
33+---
44+55+feat: retrieve CLI environment variables from `process.env` and `.env*` files
66+77+Recommended usage on CI:
88+99+- Add your secrets to `process.env` (i.e. `CF_ACCOUNT_ID`)
1010+- Add public values to the wrangler config `wrangler.jsonc` (i.e. `R2_CACHE_PREFIX_ENV_NAME`)
1111+1212+Recommended usage for local dev:
1313+1414+- Add your secrets to either a `.dev.vars*` or `.env*` file (i.e. `CF_ACCOUNT_ID`)
1515+- Add public values to the wrangler config `wrangler.jsonc` (i.e. `R2_CACHE_PREFIX_ENV_NAME`)
+4
packages/cloudflare/src/api/cloudflare-context.ts
···340340341341 const { env, cf, ctx } = await getPlatformProxy({
342342 ...options,
343343+ // The `env` passed to the fetch handler does not contain variables from `.env*` files.
344344+ // because we invoke wrangler with `CLOUDFLARE_LOAD_DEV_VARS_FROM_DOT_ENV`=`"false"`.
345345+ // Initializing `envFiles` with an empty list is the equivalent for this API call.
346346+ envFiles: [],
343347 environment,
344348 });
345349 return {
···11+import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
12import { getPlatformProxy, type GetPlatformProxyOptions } from "wrangler";
2344+import { extractProjectEnvVars } from "../build/utils/extract-project-env-vars.js";
55+36export type WorkerEnvVar = Record<keyof CloudflareEnv, string | undefined>;
4758/**
66- * Return the string env vars from the worker.
99+ * Returns the env vars to use by the CLI.
1010+ *
1111+ * The environments variables are returned from a combination of `process.env`, wrangler config, and `.env*` files.
1212+ *
1313+ * Recommended usage on CI:
1414+ *
1515+ * - Add you secrets to `process.env` (i.e. `CF_ACCOUNT_ID`)
1616+ * - Add public values to the wrangler config `wrangler.jsonc` (i.e. `R2_CACHE_PREFIX_ENV_NAME`)
1717+ *
1818+ * Note: `.dev.vars*` and `.env*` should not be checked in.
1919+ *
2020+ * Recommended usage for local dev:
2121+ *
2222+ * - Add you secrets to either a `.dev.vars*` or `.env*` file (i.e. `CF_ACCOUNT_ID`)
2323+ * - Add public values to the wrangler config `wrangler.jsonc` (i.e. `R2_CACHE_PREFIX_ENV_NAME`)
2424+ *
2525+ * Note: `.env*` files are also used by `next dev` while `.dev.var*` files are only loaded by `wrangler`.
2626+ *
2727+ * Loading details:
2828+ *
2929+ * 1. The variables are first initialized from `process.env`
3030+ * 2. They are then augmented/replaced with variables from the wrangler config (`wrangler.jsonc` and `.dev.vars*`)
3131+ * 3. They are then augmented with variables from `.env*` files (existing values are not replaced).
732 *
833 * @param options Options to pass to `getPlatformProxy`, i.e. to set the environment
3434+ * @param buildOpts Open Next build options
935 * @returns the env vars
1036 */
1111-export async function getEnvFromPlatformProxy(options: GetPlatformProxyOptions) {
1212- const envVars = {} as WorkerEnvVar;
1313- const proxy = await getPlatformProxy<CloudflareEnv>(options);
3737+export async function getEnvFromPlatformProxy(options: GetPlatformProxyOptions, buildOpts: BuildOptions) {
3838+ // 1. Start from `process.env`
3939+ const envVars = process.env;
4040+4141+ // 2. Apply vars from workers `env`
4242+ const proxy = await getPlatformProxy<CloudflareEnv>({
4343+ ...options,
4444+ // Next.js uses a different mechanism to load `.env*` files from wrangler.
4545+ // We prevent wrangler for loading the files and handle that in `getEnvFromPlatformProxy`.
4646+ envFiles: [],
4747+ });
4848+1449 Object.entries(proxy.env).forEach(([key, value]) => {
1550 if (typeof value === "string") {
5151+ // filter out bindings by only considering string values
1652 envVars[key as keyof CloudflareEnv] = value;
1753 }
1854 });
5555+1956 await proxy.dispose();
2020- return envVars;
5757+5858+ // 3. Apply new vars from `.env*` files
5959+ let mode: "production" | "development" | "test" = "production";
6060+ if (envVars.NEXTJS_ENV === "development") {
6161+ mode = "development";
6262+ } else if (envVars.NEXTJS_ENV === "test") {
6363+ mode = "test";
6464+ }
6565+6666+ const dotEnvVars = extractProjectEnvVars(mode, buildOpts);
6767+6868+ for (const varName in dotEnvVars) {
6969+ envVars[varName] ??= dotEnvVars[varName];
7070+ }
7171+7272+ return envVars as unknown as WorkerEnvVar;
2173}
22742375/**