Почему переменные окружения не работают — 3 частые причины

Знакомая боль: локально всё пашет, вписал ключ — и вдруг undefined. Или задеплоил, а на проде приложение переменную не видит.
Не спеши переписывать код. В девяти случаях из десяти виновата одна из трёх причин. И все три чинятся за минуту.
Симптом
Выглядит это всегда похоже. В коде ты берёшь process.env.МОЙ_КЛЮЧ (или через import.meta.env), а получаешь undefined. Приложение ругается «нет ключа», хотя ты его точно вписал. Пойдём от самого частого.
Причина 1. Не перезапустил
Самое частое — и самое обидное. Ты добавил переменную в файл .env, но программа этого не заметила.
Почему: переменные окружения читаются один раз, при запуске. Добавил новую при работающем сервере — он про неё не знает.
Как проверить: останови dev-сервер (Ctrl+C) и посмотри, не запущен ли он ещё со старого раза.
Как починить: перезапусти сервер. А если это сборка (Next.js, Vite и подобные) — пересобери проект заново. Переменную видно только после свежего старта.
Причина 2. .env не уехал на прод
Локально работает, на проде — нет. Классика.
Почему: файл .env лежит только у тебя на компьютере. В git его (правильно) не кладут — иначе секреты утекут. А раз его нет в репозитории, то и на сервер при деплое он не попадает. Прод искренне не знает твоих переменных.
Как проверить: зайди в настройки своего хостинга (Vercel, Netlify, Railway — где деплоишь) в раздел Environment Variables. Пусто? Вот и ответ.
Как починить: добавь каждую переменную туда руками, через панель хостинга. Имя в имя, значение в значение. После этого передеплой. Если деплой всё равно падает — глянь соседний разбор почему деплой падает.
Причина 3. Префикс и клиент-сервер
Тонкая, но частая. Переменная есть, а в браузере всё равно undefined.
Почему: секреты по умолчанию видны только на сервере. Чтобы переменная долетела до кода в браузере, её имя должно начинаться со специального префикса. В Next.js это NEXT_PUBLIC_, в Vite — VITE_. Без префикса — переменная живёт только на сервере, и это защита, а не баг.
Как проверить: ты читаешь переменную в коде, который выполняется в браузере? Тогда смотри на имя.
Как починить: нужна на клиенте — добавь префикс (NEXT_PUBLIC_..., VITE_...) и перезапусти. Но осторожно: всё с публичным префиксом видно каждому в браузере. Секретный ключ туда класть нельзя — его место на сервере (об этом — как хранить ключи).
Почему .env нельзя коммитить в git?
Потому что всё, что попало в git, легко достаётся — особенно если репозиторий открытый. Вписал ключ в .env, закоммитил, запушил — и его находят боты за минуты. Поэтому .env добавляют в .gitignore, а на прод значения заносят через панель хостинга. Если ключ уже утёк — не прячь, а сразу отзови старый и создай новый.
Переменная есть, но всё равно undefined — что ещё?
Пробегись по мелочам: опечатка в имени (API_KEY против API_kEY — регистр важен); лишние кавычки или пробелы в значении; не тот файл (.env.local против .env); или переменную читают до того, как её успели загрузить. Если ключ не работает конкретно у API-сервиса — есть отдельный чеклист: почему API-ключ не работает.
Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.





