Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Які змінні оточення потрапляють у браузер у Next.js і чому NEXT_PUBLIC_ не можна змінити після збірки?

Next.js читає .env-файли й робить змінні доступними через process.env. Але де саме вони доступні, залежить від префікса.

Без префікса - лише на сервері:

DATABASE_URL=postgres://...
STRIPE_SECRET_KEY=sk_live_...

Доступні в серверних компонентах, обробниках маршрутів, серверних функціях. У браузері process.env.STRIPE_SECRET_KEY - undefined.

З префіксом NEXT_PUBLIC_ - у браузері теж:

NEXT_PUBLIC_ANALYTICS_ID=G-XXXX
NEXT_PUBLIC_API_URL=https://api.example.com
setupAnalytics(process.env.NEXT_PUBLIC_ANALYTICS_ID);

Як це працює: під час next build Next.js підставляє значення прямо в код JavaScript, що йде в браузер. Тобто:

  • значення публічне - будь-хто побачить його в коді сторінки. Сюди можна класти лише те, що й так не секретно;
  • значення фіксується на момент збирання. Змінити NEXT_PUBLIC_API_URL на сервері після збірки - нічого не змінить у вже зібраних файлах. Один Docker-образ для staging і production з різними NEXT_PUBLIC_* не працюватиме як очікується;
  • динамічне звернення не підставляється: process.env[name] чи деструктуризація const { NEXT_PUBLIC_X } = process.env дадуть undefined у браузері.

Як передати конфігурацію під час виконання, якщо образ один на всі середовища:

  • читати змінні без префікса в серверному компоненті й передавати потрібні значення в клієнтські компоненти як props;
  • або ендпойнт конфігурації, з якого клієнт отримує налаштування.

Порядок файлів: .env.local (не в Git, перекриває все), .env.development / .env.production, .env. Змінні оточення процесу мають пріоритет над файлами.

Пастки безпеки:

  • випадково додати NEXT_PUBLIC_ до секрету - класичний витік ключа API;
  • серверний модуль з секретами, імпортований у клієнтський компонент, потрапляє в бандл - захист: пакет server-only у таких модулях дає помилку збірки при імпорті з клієнта.

Аналог у Vite (Laravel-проєкти) - префікс VITE_ і import.meta.env, з тими самими правилами: усе з префіксом публічне й фіксується при збиранні.

Докладніше в документації: Next.js: змінні оточення

Схожі питання