Использование переменных окружения в Next.js

Next.js имеет встроенную поддержку переменных окружения, что позволяет вам:

Предупреждение: Шаблон create-next-app по умолчанию гарантирует, что все файлы .env добавлены в ваш .gitignore. Почти никогда не следует коммитить эти файлы в репозиторий.

Загрузка переменных окружения

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_HOST, process.env.DB_USER и process.env.DB_PASS в окружение Node.js, позволяя использовать их в Route Handlers.

Например:

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
import { loadEnvConfig } from '@next/env'

const projectDir = process.cwd()
loadEnvConfig(projectDir)
import { loadEnvConfig } from '@next/env'

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

Затем вы можете импортировать конфигурацию там, где это необходимо. Например:

import './envConfig.ts'

export default defineConfig({
  dbCredentials: {
    connectionString: process.env.DATABASE_URL!,
  },
})
import './envConfig.js'

export default defineConfig({
  dbCredentials: {
    connectionString: process.env.DATABASE_URL,
  },
})

Ссылки на другие переменные

Next.js автоматически раскрывает переменные, использующие $ для ссылки на другие переменные, например $VARIABLE в ваших файлах .env*. Это позволяет ссылаться на другие секреты. Например:

.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 заменить все ссылки на process.env.NEXT_PUBLIC_ANALYTICS_ID в среде Node.js на значение из окружения, в котором вы запускаете next build, позволяя использовать его в любом месте вашего кода. Оно будет встроено в любой JavaScript, отправляемый в браузер.

Примечание: После сборки ваше приложение больше не будет реагировать на изменения этих переменных окружения. Например, если вы используете Heroku pipeline для продвижения сборок из одного окружения в другое или если вы развертываете один 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_. Однако эти публичные переменные окружения будут встроены в JavaScript-бандл во время next build.

Вы можете безопасно читать переменные окружения на сервере во время динамического рендеринга:

import { connection } from 'next/server'

export default async function Component() {
  await connection()
  // cookies, headers и другие Dynamic API
  // также переключатся на динамический рендеринг, что означает,
  // что эта переменная окружения вычисляется во время выполнения
  const value = process.env.MY_VALUE
  // ...
}
import { connection } from 'next/server'

export default async function Component() {
  await connection()
  // cookies, headers и другие Dynamic API
  // также переключатся на динамический рендеринг, что означает,
  // что эта переменная окружения вычисляется во время выполнения
  const value = process.env.MY_VALUE
  // ...
}

Это позволяет использовать единый Docker-образ, который можно продвигать через несколько окружений с разными значениями.

Полезно знать:

  • Вы можете выполнять код при запуске сервера с помощью функции register.
  • Мы не рекомендуем использовать опцию runtimeConfig, так как она не работает с режимом standalone output. Вместо этого мы рекомендуем постепенно переходить на маршрутизатор App, если вам нужна эта функция.

Тестовые переменные окружения

Помимо окружений development и production, доступен третий вариант: test. Так же, как вы можете установить значения по умолчанию для окружений разработки или продакшена, вы можете сделать это с файлом .env.test для тестового окружения (хотя этот вариант не так распространен, как предыдущие два). Next.js не будет загружать переменные окружения из .env.development или .env.production в тестовом окружении.

Это полезно при запуске тестов с такими инструментами, как jest или cypress, где вам нужно установить определенные переменные окружения только для целей тестирования. Значения по умолчанию для тестов будут загружены, если NODE_ENV установлен в test, хотя обычно вам не нужно делать это вручную, так как тестовые инструменты позаботятся об этом.

Есть небольшое отличие тестового окружения от development и production, о котором нужно помнить: .env.local не будет загружен, так как вы ожидаете, что тесты будут давать одинаковые результаты для всех. Таким образом, каждое выполнение тестов будет использовать одни и те же значения по умолчанию, игнорируя ваш .env.local (который предназначен для переопределения набора по умолчанию).

Полезно знать: аналогично переменным окружения по умолчанию, файл .env.test должен быть включен в ваш репозиторий, но .env.test.local не должен, так как файлы .env*.local предназначены для игнорирования через .gitignore.

При запуске модульных тестов вы можете убедиться, что ваши переменные окружения загружаются так же, как это делает Next.js, используя функцию loadEnvConfig из пакета @next/env.

// Нижеприведенный код можно использовать в файле глобальной настройки 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_ENV равен test.)
  4. .env.$(NODE_ENV)
  5. .env

Например, если NODE_ENV равен development и вы определили переменную и в .env.development.local, и в .env, будет использовано значение из .env.development.local.

Полезно знать: Допустимые значения для NODE_ENVproduction, development и test.

Полезно знать

  • Если вы используете папку /src, файлы .env.* должны оставаться в корне вашего проекта.
  • Если переменная окружения NODE_ENV не установлена, Next.js автоматически присваивает значение development при выполнении команды next dev или production для всех других команд.

История версий

ВерсияИзменения
v9.4.0Добавлена поддержка .env и NEXT_PUBLIC_.