Skip to main content

环境变量

Next.js内置支持环境变量,使您能够执行以下操作:

  • 使用.env.local加载环境变量
  • 通过添加NEXT_PUBLIC_前缀将环境变量捆绑到浏览器

加载环境变量

Next.js内置支持从.env.local加载环境变量到process.env中。

.env.local

DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword

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

# .env.local

# you can write with line breaks
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
...
Kh9NV...
...
-----END DSA PRIVATE KEY-----"

# or with `\n` inside double quotes
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END DSA PRIVATE KEY-----\n"

这会自动将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.js将自动扩展使用$引用其他变量的变量,例如在.env*文件中的$VARIABLE。这使您能够引用其他密钥。

.env

TWITTER_USER=nextjs
TWITTER_URL=https://twitter.com/$TWITTER_USER

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

note

如果需要在实际值中使用带有$的变量,它需要被转义,例如 \$

为浏览器捆绑环境变量

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

为了使环境变量的值在浏览器中可访问, Next.js可以在构建时“内联”一个值, 将其替换为交付给客户端的js捆绑中的process.env.[variable]的所有引用。 要告诉它执行此操作,只需使用NEXT_PUBLIC_前缀对变量进行前缀处理。例如:

NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk

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

note

构建后,您的应用程序将不再对这些环境变量的更改做出响应。 例如,如果您使用Heroku流水线将在一个环境中构建的slug推广到另一个环境, 或者如果您在多个环境中构建和部署单个Docker映像, 所有NEXT_PUBLIC_变量将被冻结,并在构建时评估的值,因此在项目构建时需要适当设置这些值。 如果需要访问运行时环境值,您将不得不设置自己的API以在客户端提供它们(按需或在初始化期间)。

pages/index.js

import setupAnalyticsService from '../lib/my-analytics-service'

// 'NEXT_PUBLIC_ANALYTICS_ID' can be used here as it's prefixed by 'NEXT_PUBLIC_'.
// It will be transformed at build time to `setupAnalyticsService('abcdefghijk')`.
setupAnalyticsService(process.env.NEXT_PUBLIC_ANALYTICS_ID)

function HomePage() {
return <h1>Hello World</h1>
}

export default HomePage

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

// This will NOT be inlined, because it uses a variable
const varName = 'NEXT_PUBLIC_ANALYTICS_ID'
setupAnalyticsService(process.env[varName])

// This will NOT be inlined, because it uses a variable
const env = process.env
setupAnalyticsService(env.NEXT_PUBLIC_ANALYTICS_ID)

运行时环境变量

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

默认情况下,环境变量仅在服务器上可用。 为了将环境变量暴露给浏览器,它必须以NEXT_PUBLIC_前缀开头。 但是,这些公共环境变量将在next build期间被内联到JavaScript捆绑中。

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

// import from next/cache package for dynamic functions
import { unstable_noStore as noStore } from 'next/cache'

export default function Component() {
noStore()
// cookies(), headers(), and other dynamic functions
// will also opt into dynamic rendering, making
// this env variable is evaluated at runtime
const value = process.env.MY_VALUE
// ...
}

了解:

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

默认环境变量

通常只需要一个.env.local文件。 但是,有时您可能想要为开发(next dev)或生产(next start)环境添加一些默认值。

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

.env.local始终会覆盖设置的默认值。

note

.env.env.development.env.production文件应包含在存储库中, 因为它们定义了默认值。.env*.local应添加到.gitignore中, 因为这些文件是要被忽略的。.env.local是可以存储机密的地方。

在Vercel上的环境变量

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

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

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

vercel env pull .env.local
note

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

测试环境变量

除了开发和生产环境之外,还有第三个选项:测试。 与设置开发或生产环境的默认值一样,可以使用.env.test文件为测试环境设置默认值(尽管这不像前两者那样常见)。 Next.js不会在测试环境中从.env.development.env.production加载环境变量。

当使用jestcypress等工具运行测试并需要仅用于测试目的设置特定环境变量时, 这对于设置默认值很有用。如果将NODE_ENV设置为test, 将加载测试默认值,尽管通常不需要手动执行此操作,因为测试工具将为您解决这个问题。

测试环境与开发和生产环境之间有一个小差异,您需要记住:.env.local将不会加载, 因为您期望测试为每个人产生相同的结果。 这样,通过忽略您的.env.local(旨在覆盖默认设置)来忽略每次测试执行都使用相同的env默认值。

note

类似于默认环境变量,.env.test文件应包含在存储库中,但.env.test.local不应包含在其中, 因为.env*.local的目的是通过.gitignore忽略。

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

// 以下可以在Jest全局设置文件或类似于测试设置的地方使用
import { loadEnvConfig } from '@next/env'

export default async () => {
const projectDir = process.cwd()
loadEnvConfig(projectDir)
}

环境变量加载顺序

按照以下顺序查找环境变量,一旦找到变量,就会停止。

  • process.env
  • .env.$(NODE_ENV).local
  • .env.local(当NODE_ENVtest时不会检查。)
  • .env.$(NODE_ENV)
  • .env

例如,如果 NODE_ENVdevelopment, 并且您在 .env.development.local.env 中都定义了变量, 则将使用 .env.development.local 中的值。

note

NODE_ENV 允许的值为production, developmenttest

note

如果使用的是 /src 目录,.env.* 文件应保留在项目根目录下。 如果未指定环境变量 NODE_ENV,Next.js 会在运行next dev 命令时自动指定development环境变量, 或在运行所有其他命令时自动指定production环境变量。