Menu

环境变量

示例

Next.js 内置支持环境变量,允许你执行以下操作:

加载环境变量

Next.js 内置支持从 .env* 文件中加载环境变量到 process.env

.env
DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword

值得注意的是:Next.js 还支持在 .env* 文件中使用多行变量:

# .env
 
# 你可以使用换行符写入
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
...
Kh9NV...
...
-----END DSA PRIVATE KEY-----"
 
# 或者在双引号内使用 `\n`
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END DSA PRIVATE KEY-----\n"

值得注意的是:如果你使用 /src 文件夹,请注意 Next.js 将从父文件夹加载 .env 文件,而不是/src 文件夹加载。 这会自动将 process.env.DB_HOSTprocess.env.DB_USERprocess.env.DB_PASS 加载到 Node.js 环境中,允许你在 路由处理程序 中使用它们。

例如:

app/api/route.js
export async function GET() {
  const db = await myDB.connect({
    host: process.env.DB_HOST,
    username: process.env.DB_USER,
    password: process.env.DB_PASS,
  });
  // ...
}

使用 @next/env 加载环境变量

如果你需要在 Next.js 运行时之外加载环境变量,比如在 ORM 或测试运行器的根配置文件中,你可以使用 @next/env 包。

Next.js 内部使用这个包从 .env* 文件中加载环境变量。

要使用它,请安装该包并使用 loadEnvConfig 函数来加载环境变量:

npm install @next/env
envConfig.ts
import { loadEnvConfig } from "@next/env";
 
const projectDir = process.cwd();
loadEnvConfig(projectDir);
envConfig.js
import { loadEnvConfig } from "@next/env";
 
const projectDir = process.cwd();
loadEnvConfig(projectDir);

然后,你可以在需要的地方导入配置。例如:

orm.config.ts
import "./envConfig.ts";
 
export default defineConfig({
  dbCredentials: {
    connectionString: process.env.DATABASE_URL!,
  },
});
orm.config.js
import "./envConfig.js";
 
export default defineConfig({
  dbCredentials: {
    connectionString: process.env.DATABASE_URL,
  },
});

引用其他变量

Next.js 将自动展开在 .env* 文件中使用 $ 引用其他变量的变量,例如 $VARIABLE。这允许你引用其他机密。例如:

.env
TWITTER_USER=nextjs
TWITTER_URL=https://x.com/$TWITTER_USER

在上面的例子中,process.env.TWITTER_URL 将被设置为 https://x.com/nextjs

值得注意的是:如果你需要在实际值中使用带有 $ 的变量,需要进行转义,例如 \$

为浏览器打包环境变量

NEXT_PUBLIC_ 环境变量只在 Node.js 环境中可用,这意味着它们无法在浏览器中访问 (客户端运行在不同的 环境 中)。

为了使环境变量的值在浏览器中可访问,Next.js 可以在构建时将一个值 "内联" 到传递给客户端的 js 包中,将所有对 process.env.[变量] 的引用替换为硬编码值。要让它这样做,你只需要在变量前加上 NEXT_PUBLIC_ 前缀。例如:

Terminal
NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk

这将告诉 Next.js 用你运行 next build 时环境中的值替换 Node.js 环境中所有对 process.env.NEXT_PUBLIC_ANALYTICS_ID 的引用,允许你在代码的任何地方使用它。它将被内联到发送到浏览器的任何 JavaScript 中。

值得注意的是:构建完成后,你的应用将不再响应这些环境变量的变化。例如,如果你使用 Heroku 管道将在一个环境中构建的 slug 提升到另一个环境,或者如果你构建并将单个 Docker 镜像部署到多个环境,所有 NEXT_PUBLIC_ 变量将被冻结,其值在构建时评估,因此这些值需要在项目构建时适当设置。如果你需要访问运行时环境值,你需要设置自己的 API 来向客户端提供它们 (可以按需或在初始化期间)。

pages/index.js
import setupAnalyticsService from "../lib/my-analytics-service";
 
// 'NEXT_PUBLIC_ANALYTICS_ID' 可以在这里使用,因为它以 'NEXT_PUBLIC_' 为前缀。
// 它将在构建时被转换为 `setupAnalyticsService('abcdefghijk')`。
setupAnalyticsService(process.env.NEXT_PUBLIC_ANALYTICS_ID);
 
function HomePage() {
  return <h1>Hello World</h1>;
}
 
export default HomePage;

注意,动态查找将 不会 被内联,比如:

// 这将不会被内联,因为它使用了变量
const varName = "NEXT_PUBLIC_ANALYTICS_ID";
setupAnalyticsService(process.env[varName]);
 
// 这将不会被内联,因为它使用了变量
const env = process.env;
setupAnalyticsService(env.NEXT_PUBLIC_ANALYTICS_ID);

运行时环境变量

Next.js 可以支持构建时和运行时环境变量。

默认情况下,环境变量只在服务器上可用。要将环境变量暴露给浏览器,必须以 NEXT_PUBLIC_ 为前缀。然而,这些公共环境变量将在 next build 期间被内联到 JavaScript 包中。

要读取运行时环境变量,我们建议使用 getServerSideProps逐步采用 App Router。使用 App Router,我们可以在动态渲染期间安全地在服务器上读取环境变量。这允许你使用单个 Docker 镜像,可以通过多个环境提升,具有不同的值。

import { unstable_noStore as noStore } from "next/cache";
 
export default function Component() {
  noStore();
  // cookies()、headers() 和其他动态函数
  // 也会选择动态渲染,这意味着
  // 这个环境变量在运行时进行评估
  const value = process.env.MY_VALUE;
  // ...
}

值得注意的是

  • 你可以使用 register 函数 在服务器启动时运行代码。
  • 我们不建议使用 runtimeConfig 选项,因为它不适用于独立输出模式。相反,我们建议 逐步采用 App Router。

默认环境变量

通常,只需要一个 .env* 文件。然而,有时你可能想要为 development (next dev) 或 production (next start) 环境添加一些默认值。

Next.js 允许你在 .env (所有环境)、.env.development (开发环境) 和 .env.production (生产环境) 中设置默认值。

值得注意的是.env.env.development.env.production 文件应该包含在你的代码库中,因为它们定义了默认值。所有 .env 文件默认在 .gitignore 中被排除,允许你选择将这些值提交到你的代码库。

Vercel 上的环境变量

当将你的 Next.js 应用程序部署到 Vercel 时,可以在 项目设置 中配置环境变量。

所有类型的环境变量都应该在那里配置。即使是在开发中使用的环境变量 - 随后可以 下载到你的本地设备

如果你已经配置了 开发环境变量,你可以使用以下命令将它们拉取到 .env.local 中,以在本地机器上使用:

Terminal
vercel env pull

值得注意的是:当将你的 Next.js 应用程序部署到 Vercel 时,.env* 文件中的环境变量将不会提供给 Edge Runtime,除非它们的名称以 NEXT_PUBLIC_ 为前缀。我们强烈建议在 项目设置 中管理你的环境变量,从那里所有环境变量都是可用的。

测试环境变量

除了 developmentproduction 环境外,还有第三个选项:test。与设置开发或生产环境的默认值的方式相同,你可以为 testing 环境使用 .env.test 文件做同样的事 (尽管这个不像前两个那么常见)。Next.js 不会在 testing 环境中从 .env.development.env.production 加载环境变量。

这在使用 jestcypress 等工具运行测试时很有用,你需要为测试目的设置特定的环境变量。如果 NODE_ENV 设置为 test,测试默认值将被加载,尽管你通常不需要手动执行此操作,因为测试工具会为你处理。

test 环境与 developmentproduction 环境之间有一个小区别需要注意:.env.local 不会被加载,因为你期望测试对每个人产生相同的结果。这样,每次测试执行都将使用相同的环境默认值,忽略你的 .env.local (它旨在覆盖默认设置)。

值得注意的是:与默认环境变量类似,.env.test 文件应该包含在你的代码库中,但 .env.test.local 不应该,因为 .env*.local 应该通过 .gitignore 被忽略。

在运行单元测试时,你可以通过利用 @next/env 包中的 loadEnvConfig 函数,确保以与 Next.js 相同的方式加载你的环境变量。

// 以下可以在 Jest 全局设置文件或类似的测试设置中使用
import { loadEnvConfig } from "@next/env";
 
export default async () => {
  const projectDir = process.cwd();
  loadEnvConfig(projectDir);
};

环境变量加载顺序

环境变量按以下顺序在以下位置查找,一旦找到变量就停止。

  1. process.env
  2. .env.$(NODE_ENV).local
  3. .env.local (当 NODE_ENVtest 时不检查。)
  4. .env.$(NODE_ENV)
  5. .env

例如,如果 NODE_ENVdevelopment,并且你在 .env.development.local.env 中都定义了一个变量,那么将使用 .env.development.local 中的值。

值得注意的是NODE_ENV 允许的值是 productiondevelopmenttest

注意事项

  • 如果你使用 /src 目录.env.* 文件应该保留在项目的根目录中。
  • 如果环境变量 NODE_ENV 未赋值,Next.js 会在运行 next dev 命令时自动将其赋值为 development,或在所有其他命令中赋值为 production

版本历史

版本变更
v9.4.0引入了对 .envNEXT_PUBLIC_ 的支持。