Головна
» Базові знання
»
Як виправити помилку «Supabase API Key Not Found» у змінних середовища
Як виправити помилку «Supabase API Key Not Found» у змінних середовища
Остання перевірка: 11 вересня 2026 року. Ви додаєте URL-адресу Supabase та ключ API до файлу .env, перезапускаєте додаток, але все одно отримуєте помилку, наприклад “Supabase API key not found” або власну помилку Supabase supabaseKey is required. У більшості випадків ключ існує десь, але код, який викликає createClient(), отримує undefined або порожній рядок.
За багатьма заплутаними навчальними посібниками стоїть важлива зміна назв у 2026 році. Supabase припиняє підтримку застарілих ключів API anon та service_role до кінця 2026 року та тепер рекомендує використовувати публічні (publishable) ключі для публічного/клієнтського коду та секретні (secret) ключі для довіреного серверного коду. Існуючі застарілі ключі можуть продовжувати працювати під час міграції, доки ви їх не вимкнете, але назва змінної середовища та ваш код повинні точно збігатися.
Ніколи не розміщуйте sb_secret_... у змінній, яка навмисно доступна браузерному коду, наприклад, у змінній Vite VITE_* або Next.js NEXT_PUBLIC_*. Supabase зазначає, що секретні ключі обходять безпеку на рівні рядків (Row Level Security) і повинні залишатися в компонентах бекенду, контрольованих розробником.
Крок 1: переконайтеся, що значення дійсно відсутнє під час виконання
Не починайте з регенерації ключів або перевстановлення пакетів. Спочатку доведіть, що отримує ваш додаток.
Поточний клієнт @supabase/supabase-js перевіряє другий аргумент, переданий конструктору клієнта, і генерує помилку supabaseKey is required., коли це значення є хибним (falsy). Ви можете побачити цю поведінку в офіційному вихідному коді supabase-js.
Ілюстрація помилки відсутнього ключа API Supabase, згенерована ШІ. Це не скріншот реального проєкту, а стек трасування є ілюстративним.
Для Vite використовуйте ту саму ідею з import.meta.env.
Не виводьте повний секретний ключ. Для налагодження достатньо булевого значення або очікуваного префікса. Публічний ключ призначений для публічних компонентів, але логування повних облікових даних все одно непотрібне; секретний ключ ніколи не повинен бути доступний у клієнтських логах.
Також зауважте, що синтаксис TypeScript, такий як process.env.MY_KEY! або process.env.MY_KEY as string, не створює відсутнє значення під час виконання. Він лише змінює те, що TypeScript вважає типом. Якщо змінна середовища відсутня, Supabase все одно отримає undefined.
Самоперевірка: якщо булеве значення для ключа є false, припиніть налагоджувати дозволи Supabase, автентифікацію або безпеку на рівні рядків. Додаток ще не завантажив конфігурацію.
Крок 2: використовуйте поточний тип ключа — і узгодьте старі та нові назви
Відкрийте діалогове вікно Connect вашого проєкту Supabase або перейдіть до Settings → API Keys. Поточна документація Supabase явно вказує Settings → API Keys як місце для перегляду всіх ключів API проєкту.
Для коду, який доставляється у браузер користувача, мобільний додаток, настільний додаток або інший публічний компонент, використовуйте публічний ключ (publishable key). Supabase стверджує, що публічний ключ безпечно розкривати, оскільки доступ до бази даних все ще контролюється грантами та безпекою на рівні рядків. Для компонентів бекенду, які ви повністю контролюєте, секретний ключ (secret key) надає підвищений доступ і обходить безпеку на рівні рядків.
Міграція від застарілих ключів є поширеною причиною помилки “not found”, оскільки наступні комбінації не є еквівалентними як назви змінних середовища:
Код читає
Середовище визначає
Результат
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
Збіг
NEXT_PUBLIC_SUPABASE_ANON_KEY
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
Старий код читає undefined
VITE_SUPABASE_PUBLISHABLE_KEY
SUPABASE_PUBLISHABLE_KEY
Клієнт Vite за замовчуванням не розкриває змінну без префікса
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
VITE_SUPABASE_PUBLISHABLE_KEY
Неправильне іменування/патерн доступу для фреймворку
Старіша змінна, така як NEXT_PUBLIC_SUPABASE_ANON_KEY, не є автоматично недійсною. Якщо у вашому проєкті все ще є активний застарілий ключ anon і ваш код читає саме цю змінну, він може продовжувати працювати під час періоду міграції Supabase. Проблема полягає в копіюванні нового публічного ключа в одну назву змінної, тоді як код все ще читає іншу.
Самоперевірка: шукайте у своєму проєкті SUPABASE_. Порівняйте кожну назву змінної в коді з точними назвами у ваших файлах середовища та налаштуваннях розгортання. Не покладайтеся на пам'ять.
Крок 3: розмістіть файл .env там, де ваш фреймворк дійсно його завантажує
Правильний ключ у неправильному місці файлу фактично є відсутнім ключем.
Ілюстрація дерева проєкту, згенерована ШІ, що показує файл середовища в корені додатка. Це не скріншот конкретного IDE або проєкту фреймворку.
Next.js: тримайте файли .env у корені проєкту
Next.js має вбудовану підтримку файлів .env*. Його поточний посібник зі змінних середовища стверджує, що якщо ви використовуєте директорію /src, файли середовища все одно належать до кореня проєкту, а не всередину /src. Перегляньте офіційний посібник Next.js зі змінних середовища.
Типова структура:
my-app/
.env.local
package.json
next.config.js
app/
src/ # if used
Для коду на стороні браузера Next.js розкриває лише змінні, які використовують префікс NEXT_PUBLIC_. Ці значення вбудовуються в браузерний пакет під час збірки.
Vite: використовуйте VITE_ та import.meta.env
Vite розкриває змінні середовища клієнта через import.meta.env. За замовчуванням лише назви з префіксом VITE_ розкриваються для клієнтського коду. Офіційний посібник Vite щодо змінних середовища та режимів документує це безпосередньо.
оскільки йому бракує стандартного префікса розкриття VITE_.
Код Node/сервера: не копіюйте префікси браузера навмання
Серверний код зазвичай читає з process.env. Якщо ключ не повинен бути доступний у браузері, не додавайте публічний префікс лише для того, щоб зробити його видимим. Supabase спеціально попереджає, що секретні ключі призначені лише для бекенду.
Самоперевірка: перевірте три речі разом: файл env знаходиться в корені додатка, назва змінної використовує правильний префікс фреймворку, а код використовує правильний доступ фреймворку — process.env для Next.js/Node або import.meta.env для клієнтського коду Vite.
Крок 4: перезапустіть сервер розробки після зміни файлів середовища
Змінні середовища зазвичай завантажуються при запуску процесу розробки. Vite явно документує, що файли .env завантажуються при запуску, і що після змін слід перезапустити сервер.
Зупиніть поточний процес і запустіть його знову:
# Next.js
npm run dev
# Vite
npm run dev
Ілюстрація терміналу, згенерована ШІ, що показує перезапуск сервера розробки та досягнення чистого запуску. Це не вивід реального розгортання Supabase.
Якщо помилка з'явилася лише після того, як ви створили файл середовища, коли сервер уже працював, перезапуск може бути повним виправленням.
Самоперевірка: повторно запустіть тимчасові булеві перевірки. Якщо значення тепер завантажені, видаліть непотрібний вивід налагодження та продовжуйте звичайну роботу з Supabase.
Використовуйте захист під час виконання замість приховування проблеми за допомогою TypeScript
Корисним шаблоном для продакшену є завершення роботи з чітким повідомленням про конфігурацію перед викликом Supabase:
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
if (!supabaseUrl) {
throw new Error('NEXT_PUBLIC_SUPABASE_URL is missing')
}
if (!supabaseKey) {
throw new Error('NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY is missing')
}
export const supabase = createClient(supabaseUrl, supabaseKey)
Ілюстрація коду, згенерована ШІ, що показує перевірку конфігурації перед викликом createClient(). Це концептуальний приклад, а не скріншот з документації SDK Supabase.
коли ви вирішуєте проблеми, оскільки твердження про ненульове значення може приховати попередження TypeScript, не змінюючи значення під час виконання.
Якщо це працює локально, але не вдається після розгортання
Зазвичай це проблема середовища розгортання, а не проєкту Supabase.
Локальні файли .env.local зазвичай не фіксуються в Git — і не повинні розглядатися як механізм доставки секретів для продакшену. Налаштуйте ті самі назви змінних у налаштуваннях проєкту вашого хостинг-провайдера.
Наприклад, Vercel документує окремі середовища Production, Preview та Development. Також зазначається, що зміни змінних середовища застосовуються лише до нових розгортань, тому після додавання або зміни їх потрібно повторно розгорнути. Перегляньте офіційний посібник Vercel з управління змінними середовища.
Перевірте:
Чи визначена змінна для Production, а не лише для Preview?
Чи точно назва збігається з кодом?
Чи було створено нове розгортання після додавання змінної?
Чи була публічна змінна присутня під час збірки клієнтського пакета?
Публічні змінні Next.js є значеннями під час збірки
Next.js документує, що змінні NEXT_PUBLIC_* вбудовуються в браузерний JavaScript під час збірки. Після збірки додатка зміна середовища виконання не переписує ці значення в існуючому клієнтському пакеті. Якщо ви зберете образ Docker без NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY і пізніше ін'єктуєте його лише при запуску контейнера, браузерний код все ще може містити відсутнє значення під час збірки.
Виправлення: надайте публічні значення Supabase під час збірки, яка створює клієнтський пакет, або перепроєктуйте додаток, щоб надавати конфігурацію під час виконання через механізм, контрольований сервером.
Vite також замінює значення середовища клієнта під час збірки
Документація Vite стверджує, що константи import.meta.env статично замінюються під час пакування. Тому, якщо локальна розробка працює, але продакшн-пакет ні, переконайтеся, що VITE_SUPABASE_URL та VITE_SUPABASE_PUBLISHABLE_KEY існували в середовищі збірки — а не лише на машині, яка пізніше обслуговує статичні файли.
Монорепозиторії: перевірте, яка директорія є фактичним коренем додатка
Якщо команда Next.js або Vite запускається з apps/web як коренем додатка, файл середовища, розміщений лише в repo/.env.local, може не бути тим файлом, який завантажує фреймворк. envDir у Vite за замовчуванням вказує на корінь проєкту, а Next.js очікує свої файли .env* в корені проєкту Next.js.
Виправлення: визначте директорію, що містить package.json та конфігурацію фреймворку додатка, потім розмістіть файл env там, де його очікує цей додаток, або явно налаштуйте директорію середовища, якщо фреймворк це підтримує.
Supabase Edge Functions використовують інші поточні назви змінних за замовчуванням
Якщо помилка виникає всередині Supabase Edge Function, не копіюйте навмання приклад Next.js або Vite.
Зверніть увагу, що SUPABASE_PUBLISHABLE_KEYS та SUPABASE_SECRET_KEYS є множинними. Посібник з міграції Supabase пояснює, що ці нові змінні містять JSON-об'єкти, ключі яких відповідають назвам ключів API. Для секретного ключа за замовчуванням:
const secretKeys = JSON.parse(
Deno.env.get('SUPABASE_SECRET_KEYS') ?? '{}'
)
const secretKey = secretKeys['default']
if (!secretKey) {
throw new Error('Default Supabase secret key is missing')
}
Під час міграції застарілі змінні Edge Function, такі як SUPABASE_ANON_KEY та SUPABASE_SERVICE_ROLE_KEY, можуть існувати поряд із новими словниками ключів. Не припускайте, що назва змінної зі старого навчального посібника по функціях збігається з новим типом ключа, який ви щойно створили.
Не вирішуйте помилку, розкриваючи секретний ключ
Спокусливим “виправленням” є додавання NEXT_PUBLIC_ або VITE_ до серверного секрету, щоб браузер нарешті зміг його прочитати. Це може усунути помилку відсутньої змінної, але створити проблему безпеки.
Поточний посібник Supabase щодо ключів API є чітким:
Публічний ключ (Publishable key): призначений для публічних компонентів, таких як браузери та мобільні додатки.
Секретний ключ (Secret key): призначений лише для компонентів бекенду, які ви контролюєте; він обходить безпеку на рівні рядків.
Якщо секретний ключ був розкритий у вихідному коді, публічному пакеті, скріншоті або репозиторії, видаліть або ротаційте його через налаштування API Keys у Supabase, замість простого перейменування змінної середовища.
Поширені симптоми та найшвидша перевірка
Симптом
Найімовірніше місце для пошуку
supabaseKey is required. одразу при запуску
Другий аргумент для createClient() є порожнім або undefined
Next.js працює на сервері, але ключ undefined у Client Component
Відсутній префікс NEXT_PUBLIC_, неправильна назва або відсутнє значення під час збірки
Vite показує undefined
Відсутній префікс VITE_ або використання process.env замість import.meta.env
Працює локально, не вдається на продакшені
Змінні середовища хостингу, область Production/Preview або відсутня перебудова/перерозгортання
Працювало з ANON_KEY, зламалося після міграції
Код і файл env використовують різні старі/нові назви змінних
Edge Function не може знайти SUPABASE_SECRET_KEY
Поточні значення за замовчуванням Edge Function використовують SUPABASE_SECRET_KEYS як JSON-словник
TypeScript компілюється після додавання !, але виконання все ще не вдається
Твердження змінило лише тип; значення середовища все ще відсутнє
Фінальна самоперевірка: перевірте конфігурацію в правильному порядку
Перш ніж оголошувати проблему виправленою, виконайте цей чек-лист:
Підтвердіть, що Project URL Supabase походить з проєкту, який ви дійсно збираєтеся використовувати.
Для браузерного/клієнтського коду підтвердіть, що ви використовуєте поточний публічний (publishable) ключ або все ще активний застарілий ключ anon — а не секретний ключ.
Підтвердіть, що код і файл середовища використовують однакові назви змінних.
Для клієнтського коду Next.js використовуйте NEXT_PUBLIC_* та прямі посилання process.env.VARIABLE_NAME.
Для клієнтського коду Vite використовуйте VITE_* та import.meta.env.VARIABLE_NAME.
Тримайте .env.local в корені додатка, а не всередині /src.
Перезапустіть сервер розробки після редагування файлів середовища.
Для продакшену встановіть значення у правильному середовищі розгортання та перебудуйте/перерозгорніть.
Не логуєте та не розкривайте ключі sb_secret_....
Видаліть тимчасові логи налагодження після підтвердження конфігурації.
Коли createClient() ініціалізується без помилки відсутнього ключа, проблема зі змінними середовища вирішена. Якщо наступний запит до Supabase повертає помилку авторизації, безпеки на рівні рядків або дозволу таблиці, розглядайте це як окрему проблему. Дійсний ключ API не гарантує, що викликач має дозвіл читати або змінювати кожен рядок; Supabase навмисно розділяє ідентифікацію ключа API, автентифікацію користувача та авторизацію бази даних.
Тривале виправлення — це не “перейменовуйте ключ, доки не запрацює”. Це узгодження чотирьох речей: поточного типу ключа Supabase, назви змінної середовища, правил розкриття фреймворку та середовища, в якому додаток фактично збирається або виконується. Коли вони збігаються, клієнт Supabase отримує справжній ключ замість undefined, і оманливий цикл конфігурації закінчується.