如何在 Next.js 中使用環境變數

Next.js 內建支援環境變數,讓您可以實現以下功能:

警告: 預設的 create-next-app 模板會確保所有 .env 檔案都被加入您的 .gitignore。您幾乎不會想將這些檔案提交到儲存庫中。

載入環境變數

Next.js 內建支援從 .env* 檔案載入環境變數到 process.env 中。

.env
DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword

這會自動將 process.env.DB_HOSTprocess.env.DB_USERprocess.env.DB_PASS 載入到 Node.js 環境中,讓您可以在 Next.js 資料獲取方法API 路由 中使用。

例如,使用 getStaticProps

pages/index.js
export async function getStaticProps() {
  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
import { loadEnvConfig } from '@next/env'

const projectDir = process.cwd()
loadEnvConfig(projectDir)

然後,您可以在需要的地方導入配置。例如:

import './envConfig.ts'

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.[variable] 的引用替換為硬編碼的值。要實現這一點,您只需在變數前加上 NEXT_PUBLIC_。例如:

Terminal
NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk

這會告訴 Next.js 在 Node.js 環境中將所有對 process.env.NEXT_PUBLIC_ANALYTICS_ID 的引用替換為運行 next build 時的環境值,讓您可以在程式碼的任何地方使用它。它會被內聯到所有傳送給瀏覽器的 JavaScript 中。

注意: 建置完成後,您的應用程式將不再回應這些環境變數的變更。例如,如果您使用 Heroku pipeline 將在一個環境中建置的 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

這讓您可以使用單一的 Docker 映像,並在多個環境中推廣,同時使用不同的值。

小知識:

  • 您可以使用 register 函數 在伺服器啟動時運行程式碼。
  • 我們不建議使用 runtimeConfig 選項,因為這不適用於獨立輸出模式。相反,如果您需要此功能,我們建議 逐步採用 App Router。

測試環境變數

除了 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_ 前綴引入。

On this page