Як виправити помилку «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) ключі для довіреного серверного коду. Існуючі застарілі ключі можуть продовжувати працювати під час міграції, доки ви їх не вимкнете, але назва змінної середовища та ваш код повинні точно збігатися.

У поточній документації Supabase використовуються значення, такі як sb_publishable_... та sb_secret_.... Перегляньте офіційний посібник Supabase щодо ключів API та посібник з міграції на публічні та секретні ключі.

Швидке виправлення: узгодьте назви змінних із фреймворком та кодом

Для поточного браузерного клієнта Next.js офіційний швидкий старт Supabase використовує:

NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...

та:

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 || !supabaseKey) {
  throw new Error('Supabase environment variables are missing')
}

export const supabase = createClient(supabaseUrl, supabaseKey)

Для поточного браузерного клієнта Vite/React офіційний швидкий старт React від Supabase використовує:

VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...

і ви читаєте їх за допомогою:

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseKey = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY

Для серверного коду, якому дійсно потрібен підвищений доступ, посібник Supabase щодо ключів API показує такий шаблон:

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SECRET_KEY=sb_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
Ілюстрація помилки відсутнього ключа API Supabase, згенерована ШІ. Це не скріншот реального проєкту, а стек трасування є ілюстративним.

Додайте тимчасовий захист перед createClient():

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY

console.log('Supabase URL loaded:', Boolean(supabaseUrl))
console.log('Supabase key loaded:', Boolean(supabaseKey))
console.log(
  'Key type:',
  supabaseKey?.startsWith('sb_publishable_') ? 'publishable' : 'other/missing'
)

if (!supabaseUrl || !supabaseKey) {
  throw new Error('Supabase environment variables are missing')
}

Для 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_KEYNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYЗбіг
NEXT_PUBLIC_SUPABASE_ANON_KEYNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYСтарий код читає undefined
VITE_SUPABASE_PUBLISHABLE_KEYSUPABASE_PUBLISHABLE_KEYКлієнт Vite за замовчуванням не розкриває змінну без префікса
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYVITE_SUPABASE_PUBLISHABLE_KEYНеправильне іменування/патерн доступу для фреймворку

Старіша змінна, така як NEXT_PUBLIC_SUPABASE_ANON_KEY, не є автоматично недійсною. Якщо у вашому проєкті все ще є активний застарілий ключ anon і ваш код читає саме цю змінну, він може продовжувати працювати під час періоду міграції Supabase. Проблема полягає в копіюванні нового публічного ключа в одну назву змінної, тоді як код все ще читає іншу.

Самоперевірка: шукайте у своєму проєкті SUPABASE_. Порівняйте кожну назву змінної в коді з точними назвами у ваших файлах середовища та налаштуваннях розгортання. Не покладайтеся на пам'ять.

Крок 3: розмістіть файл .env там, де ваш фреймворк дійсно його завантажує

Правильний ключ у неправильному місці файлу фактично є відсутнім ключем.

Ілюстрація провідника проєкту, згенерована ШІ, що показує файл середовища в корені проєкту поруч із package.json
Ілюстрація дерева проєкту, згенерована ШІ, що показує файл середовища в корені додатка. Це не скріншот конкретного 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:

VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...
const url = import.meta.env.VITE_SUPABASE_URL
const key = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY

Зазвичай це буде undefined у браузерному коді Vite:

const key = import.meta.env.SUPABASE_PUBLISHABLE_KEY

оскільки йому бракує стандартного префікса розкриття 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)
Ілюстрація коду, згенерована ШІ, що показує захист під час виконання перед створенням клієнта Supabase
Ілюстрація коду, згенерована ШІ, що показує перевірку конфігурації перед викликом createClient(). Це концептуальний приклад, а не скріншот з документації SDK Supabase.

Це краще, ніж:

createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!
)

коли ви вирішуєте проблеми, оскільки твердження про ненульове значення може приховати попередження 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 існували в середовищі збірки — а не лише на машині, яка пізніше обслуговує статичні файли.

Монорепозиторії: перевірте, яка директорія є фактичним коренем додатка

Монорепозиторій може містити:

repo/
  package.json
  apps/
    web/
      package.json
      .env.local
      app/
  packages/
    ui/

Якщо команда 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 щодо змінних середовища Edge Functions перелічує ці секретні дані за замовчуванням, серед інших:

  • SUPABASE_URL
  • SUPABASE_DB_URL
  • SUPABASE_PUBLISHABLE_KEYS
  • SUPABASE_SECRET_KEYS
  • SUPABASE_JWKS

Зверніть увагу, що 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 компілюється після додавання !, але виконання все ще не вдаєтьсяТвердження змінило лише тип; значення середовища все ще відсутнє

Фінальна самоперевірка: перевірте конфігурацію в правильному порядку

Перш ніж оголошувати проблему виправленою, виконайте цей чек-лист:

  1. Підтвердіть, що Project URL Supabase походить з проєкту, який ви дійсно збираєтеся використовувати.
  2. Для браузерного/клієнтського коду підтвердіть, що ви використовуєте поточний публічний (publishable) ключ або все ще активний застарілий ключ anon — а не секретний ключ.
  3. Підтвердіть, що код і файл середовища використовують однакові назви змінних.
  4. Для клієнтського коду Next.js використовуйте NEXT_PUBLIC_* та прямі посилання process.env.VARIABLE_NAME.
  5. Для клієнтського коду Vite використовуйте VITE_* та import.meta.env.VARIABLE_NAME.
  6. Тримайте .env.local в корені додатка, а не всередині /src.
  7. Перезапустіть сервер розробки після редагування файлів середовища.
  8. Для продакшену встановіть значення у правильному середовищі розгортання та перебудуйте/перерозгорніть.
  9. Не логуєте та не розкривайте ключі sb_secret_....
  10. Видаліть тимчасові логи налагодження після підтвердження конфігурації.

Коли createClient() ініціалізується без помилки відсутнього ключа, проблема зі змінними середовища вирішена. Якщо наступний запит до Supabase повертає помилку авторизації, безпеки на рівні рядків або дозволу таблиці, розглядайте це як окрему проблему. Дійсний ключ API не гарантує, що викликач має дозвіл читати або змінювати кожен рядок; Supabase навмисно розділяє ідентифікацію ключа API, автентифікацію користувача та авторизацію бази даних.

Тривале виправлення — це не “перейменовуйте ключ, доки не запрацює”. Це узгодження чотирьох речей: поточного типу ключа Supabase, назви змінної середовища, правил розкриття фреймворку та середовища, в якому додаток фактично збирається або виконується. Коли вони збігаються, клієнт Supabase отримує справжній ключ замість undefined, і оманливий цикл конфігурації закінчується.

Залишити коментар

Як виправити помилку “Prisma Client Has Not Been Generated Yet”

Як виправити помилку “Prisma Client Has Not Been Generated Yet”

Виправте помилку незгенерованого Prisma Client, перевіривши генератор, схему, шлях виводу, імпорти, версії, налаштування монорепозиторію та кроки збірки під час розгортання.

Як виправити помилку SSL-сертифіката: не вдалося отримати локальний сертифікат емітента в Git

Як виправити помилку SSL-сертифіката: не вдалося отримати локальний сертифікат емітента в Git

Виправте помилку Git «не вдалося отримати локальний сертифікат емітента», визначивши механізм довіри, встановивши правильний ланцюжок ЦС та зберігаючи перевірку SSL увімкненою.

Як виправити помилку таймауту мережі MongoDB у з'єднанні Mongoose

Як виправити помилку таймауту мережі MongoDB у з'єднанні Mongoose

Виправте помилки таймауту мережі MongoDB у Mongoose, визначивши тип таймауту, перевіривши доступність Atlas або TCP, виправивши URI та налаштувавши таймаути лише за необхідності.

Як виправити помилку «Execution Policy Restricted» у Windows PowerShell

Як виправити помилку «Execution Policy Restricted» у Windows PowerShell

Виправте помилку обмеженої політики виконання PowerShell, перевіривши область дії та групову політику, а потім обравши RemoteSigned, Unblock-File або тимчасовий параметр сесії.

Як виправити помилку npm ERR! code ERESOLVE: конфлікт залежностей-партнерів

Як виправити помилку npm ERR! code ERESOLVE: конфлікт залежностей-партнерів

Виправте конфлікти залежностей-партнерів npm ERESOLVE, визначивши несумісний діапазон пакетів, узгодивши версії, використовуючи npm explain та npm ls, а також розглядаючи legacy-peer-deps або force лише як контрольовані резервні варіанти.

Як виправити помилку підключення Redis до 127.0.0.1:6379

Як виправити помилку підключення Redis до 127.0.0.1:6379

Виправте помилки відмови у підключенні Redis на 127.0.0.1:6379, перевіривши сервер, порт, мережу Docker, redis.conf, автентифікацію та TLS.

Як виправити внутрішню помилку 500 у серверних компонентах Next.js

Як виправити внутрішню помилку 500 у серверних компонентах Next.js

Виправте помилки 500 у серверних компонентах Next.js, аналізуючи логи сервера, перевіряючи запити даних та змінні середовища, обробляючи помилки та перевіряючи збірку для продакшену.

Як виправити помилку CrashLoopBackOff у Kubernetes у локальному Minikube

Як виправити помилку CrashLoopBackOff у Kubernetes у локальному Minikube

Діагностуйте та виправляйте помилку CrashLoopBackOff у Kubernetes у локальному Minikube, перевіряючи стан пода, попередні логи, причини завершення роботи, проби, конфігурацію, ліміти пам’яті та стан кластера.

Як виправити помилку «Docker Desktop Engine Stopped» у Windows 11

Як виправити помилку «Docker Desktop Engine Stopped» у Windows 11

Виправте помилку «Docker Desktop Engine Stopped» у Windows 11, перевіривши статус Docker, оновивши та перезавантаживши WSL 2, підтвердивши віртуалізацію та використавши діагностику перед скиданням налаштувань.

Як виправити помилку Uncaught ReferenceError: process is not defined у Vite

Як виправити помилку Uncaught ReferenceError: process is not defined у Vite

Виправте помилку 'process is not defined' у Vite, замінивши використання process.env у стилі Node.js, правильно налаштувавши змінні VITE_ та перевіривши залежності.