[{"data":1,"prerenderedAt":1190},["ShallowReactive",2],{"blog-uk-supabase-auth-redirects-to-localhost":3,"blog-index-uk":660},{"id":4,"title":5,"body":6,"category":617,"cover":618,"coverAlt":619,"description":620,"draft":621,"extension":622,"faq":623,"image":639,"keywords":640,"meta":648,"navigation":649,"ogTitle":650,"path":651,"published":652,"seo":653,"stem":654,"tldr":655,"updated":652,"__hash__":659},"blog_uk\u002Fblog\u002Fsupabase-auth-redirects-to-localhost.md","Чому Supabase перенаправляє посилання з листів на localhost:3000",{"type":7,"value":8,"toc":605},"minimark",[9,13,24,31,38,46,51,54,73,79,94,98,101,132,154,166,172,179,183,186,216,220,223,236,239,243,254,279,297,318,338,406,412,416,419,426,439,442,445,481,486,489,496,500,503,512,526,535,555,559,593],[10,11,12],"p",{},"Новий користувач реєструється у вашому робочому застосунку, відкриває лист із\nпідтвердженням і натискає кнопку. Його браузер відкриває сторінку з написами\n\"This site can't be reached\" і \"localhost refused to connect\" (так в\nангломовному Chrome), над адресою, яка починається так:",[14,15,20],"pre",{"className":16,"code":18,"language":19},[17],"language-text","http:\u002F\u002Flocalhost:3000\u002F#access_token=…&expires_at=…&expires_in=…&refresh_token=…&sb=&token_type=bearer&type=signup\n","text",[21,22,18],"code",{"__ignoreMap":23},"",[10,25,26,27,30],{},"Якщо ваш застосунок використовує потік PKCE, вона натомість закінчується на\n",[21,28,29],{},"?code=…",". Ви збудували застосунок у Lovable, Bolt, v0, Cursor, Claude Code чи\nReplit, у попередньому перегляді він працював бездоганно, а вхід із паролем\nдосі працює.",[10,32,33,34,37],{},"Перенаправлення Supabase на localhost означає, що Supabase Auth, частина\nSupabase, яка впускає людей, виконала свою роботу, а потім відправила людину на\nSite URL вашого проєкту, де досі стоїть ",[21,35,36],{},"http:\u002F\u002Flocalhost:3000",". Ця адреса\nозначає \"цей компʼютер\". На компʼютері вашого користувача там нічого немає.\nВиправлення складається з двох налаштувань на одній сторінці панелі Supabase.",[10,39,40,41,45],{},"Ось у чому помиляються швидкі поради в мережі: ",[42,43,44],"strong",{},"маска, яка прибирає це\nповідомлення одним рядком, водночас дозволяє посиланню незнайомця відправити\nваших користувачів на його сторінку вже з виконаним входом."," Налаштування нижче\nзмушують посилання працювати й тримають ці двері зачиненими.",[47,48,50],"h2",{"id":49},"що-означає-перенаправлення-supabase-на-localhost","Що означає перенаправлення Supabase на localhost?",[10,52,53],{},"Воно означає, що Supabase відправив людину на типову адресу вашого проєкту, бо\nне прийняв кращої.",[10,55,56,57,64,65,68,69,72],{},"Кожен лист, який Supabase надсилає за вас, чи то підтвердження реєстрації,\nmagic link, скидання пароля чи запрошення, спершу веде на власну адресу вашого\nпроєкту.\n",[58,59,63],"a",{"href":60,"rel":61},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fauth\u002Fauth-email-templates",[62],"nofollow","Посібник із шаблонів листів","\nSupabase показує форму:\n",[21,66,67],{},"https:\u002F\u002Fproject-ref.supabase.co\u002Fauth\u002Fv1\u002Fverify?token=…&type=email&redirect_to=https:\u002F\u002Fexample.com\u002Fpath",".\nТам Supabase перевіряє токен, а потім відправляє браузер туди, куди вказує\n",[21,70,71],{},"redirect_to",".",[10,74,75,76,78],{},"Уявіть дороговказ біля дверей Supabase. Кожна людина, яка відкриває посилання,\nвходить біля дверей, а потім іде далі з ключем у руці вздовж однієї зі стрілок.\nСтрілки ставите ви. Site URL і є тією стрілкою, якою йдуть усі, коли жодна\nінша не підходить, і в новому проєкті вона показує на ",[21,77,36],{},": майстерню,\nде збудували застосунок, а на будь-чиїй іншій машині порожню кімнату.",[10,80,81,86,87,90,91,93],{},[58,82,85],{"href":83,"rel":84},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fauth\u002Fredirect-urls",[62],"Посібник із перенаправлень","\nSupabase каже, що Site URL задає типове перенаправлення, коли в коді не вказано\n",[21,88,89],{},"redirectTo",", просить змінити її з ",[21,92,36],{}," на вашу робочу\nадресу й називає це налаштування критично важливим для підтверджень поштою та\nскидання паролів.",[47,95,97],{"id":96},"чому-supabase-ігнорує-адресу-яку-попросив-мій-застосунок","Чому Supabase ігнорує адресу, яку попросив мій застосунок?",[10,99,100],{},"Тому що цієї адреси немає у вашому списку Redirect URLs, і Supabase бере іншу,\nнічого вам не кажучи.",[10,102,103,104,107,108,111,112,115,116,118,119,111,122,125,126,131],{},"Ваш застосунок може вказати, куди людям потрапити. У JavaScript-бібліотеці\nSupabase це ",[21,105,106],{},"emailRedirectTo"," у ",[21,109,110],{},"signUp"," і ",[21,113,114],{},"signInWithOtp"," та ",[21,117,89],{}," у\n",[21,120,121],{},"resetPasswordForEmail",[21,123,124],{},"signInWithOAuth",". Далі Supabase Auth вирішує в\n",[58,127,130],{"href":128,"rel":129},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fauth\u002Fblob\u002Fmaster\u002Finternal\u002Futilities\u002Frequest.go",[62],"короткій функції",",\nу такому порядку:",[133,134,135,142,148],"ol",{},[136,137,138,141],"li",{},[42,139,140],{},"Адреса, яку попросив ваш застосунок",", якщо вона збігається із записом у\nвашому списку Redirect URLs або лежить на тому самому домені, що й ваша\nSite URL.",[136,143,144,147],{},[42,145,146],{},"Адреса сторінки, з якої прийшов запит",", як її передав браузер, за тим\nсамим правилом.",[136,149,150,153],{},[42,151,152],{},"Інакше Site URL."," Supabase не видає жодної помилки, а консоль вашого\nзастосунку нічого не показує.",[10,155,156,157,162,163,165],{},"Це рішення ухвалюється, коли лист надсилають, і обрана адреса потрапляє в\nпосилання. Коли хтось відкриває посилання, Supabase ще раз перевіряє цю адресу\nза вашими налаштуваннями такими, якими вони є в цю мить. Власна\n",[58,158,161],{"href":159,"rel":160},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Ftroubleshooting\u002Fwhy-am-i-being-redirected-to-the-wrong-url-when-using-auth-redirectto-option-_vqIeO",[62],"відповідь Supabase з усунення несправностей","\nзводить правило до одного речення: щоб опція ",[21,164,89],{}," спрацювала, треба\nвнести точну URL-адресу в налаштування Redirect URLs.",[167,168],"diagram",{"alt":169,"caption":170,"src":171},"Посилання з листа доходить до дороговказу з трьома стрілками. Дві перші, для адреси, яку попросив застосунок, і для сторінки, з якої прийшов запит, по черзі перевіряють за списком і перекреслюють. Третя стрілка, Site URL, веде людину до ноутбука з темним екраном і червоним хрестиком.","Supabase пробує адресу, яку попросив ваш застосунок, потім сторінку, з якої прийшов запит. Коли жодної з них немає у списку, вирішує Site URL.","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fthree-tries-1600x760.png",[10,173,174,175,72],{},"Те саме налаштування вирішує, куди \"Sign in with Google\" повертає людей, тож\nкнопка Google, яка приводить на localhost, має ту саму причину. Якщо ж кнопка\nGoogle зупиняється раніше, на сторінці з \"Unsupported provider: provider is not\nenabled\", справа в іншому:\n",[58,176,178],{"href":177},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","у перемикачі в Supabase і списку в Google",[47,180,182],{"id":181},"чому-ви-не-побачили-цього-до-запуску","Чому ви не побачили цього до запуску",[10,184,185],{},"Тому що обидва способи, якими ви перевіряли, ніколи не доходять до Site URL.",[187,188,189,195,201],"ul",{},[136,190,191,194],{},[42,192,193],{},"Вхід із паролем відбувається всередині сторінки."," Немає ні посилання з\nлиста, ні проходу через двері Supabase, тож дороговказ ніхто не читає.",[136,196,197,200],{},[42,198,199],{},"Якщо ви будуєте в Cursor чи Claude Code і ваш сервер розробки працював на\nпорту 3000",", коли ви перевіряли лист, посилання відкрило вашу власну\nлокальну копію й виглядало так, ніби все працює.",[136,202,203,206,211,212,215],{},[42,204,205],{},"На вбудованому бекенді Lovable ви, можливо, ніколи з цим не зіткнетеся.",[58,207,210],{"href":208,"rel":209},"https:\u002F\u002Fdocs.lovable.dev\u002Ffeatures\u002Fauthentication",[62],"Документація Lovable про автентифікацію","\nкаже, що під час публікації він ставить у Site URL вашу опубліковану адресу на\n",[21,213,214],{},"lovable.app",", а власний домен додає до redirect URLs, коли ви його\nпідключаєте. Та сама сторінка каже, що застосунки з вашим власним проєктом\nSupabase не отримують автоматичних оновлень.",[47,217,219],{"id":218},"чи-підтверджений-обліковий-запис-хоча-сторінка-не-відкрилася","Чи підтверджений обліковий запис, хоча сторінка не відкрилася?",[10,221,222],{},"Так, якщо це підтвердження реєстрації. Supabase спершу підтверджує і лише потім\nвідправляє браузер далі.",[10,224,225,226,231,232,72],{},"У\n",[58,227,230],{"href":228,"rel":229},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fauth\u002Fblob\u002Fmaster\u002Finternal\u002Fapi\u002Fverify.go",[62],"коді, який обробляє посилання",",\nобліковий запис підтверджується до того, як іде перенаправлення. Сторінка, що\nне відкривається, зʼявляється, коли роботу вже зроблено. Тож скажіть людині,\nщо вона може увійти на вашому робочому сайті з паролем, який обрала. Повторне\nнатискання того самого листа не допоможе: посилання спрацьовує один раз, а на\nдруге натискання приходить\n",[58,233,235],{"href":234},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","\"Email link is invalid or has expired\"",[10,237,238],{},"Magic link чи скидання пароля працюють інакше. Цей вхід пішов на localhost і\nтам лишився, тож коли ви виправите налаштування, людині потрібен новий лист.",[47,240,242],{"id":241},"як-виправити-перенаправлення-supabase-на-localhost","Як виправити перенаправлення Supabase на localhost",[10,244,245,246,249,250,253],{},"Змініть Site URL, а потім внесіть у список інші адреси, куди ви відправляєте\nлюдей. Обидва налаштування є на сторінці ",[42,247,248],{},"URL Configuration"," у розділі\n",[42,251,252],{},"Authentication"," панелі Supabase.",[10,255,256,263,266,267,269,270,274,275,278],{},[42,257,258,259,262],{},"Поставте в Site URL свою робочу адресу з ",[21,260,261],{},"https:\u002F\u002F"," попереду.",[21,264,265],{},"https:\u002F\u002Fyourapp.com",", повністю. Без ",[21,268,261],{}," Supabase читає її як шлях на\nвласній адресі, і людина натомість потрапляє у ваш проєкт Supabase з\n",[58,271,273],{"href":272},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\"",". Після цього\nбудь-яку адресу на цьому домені приймають з будь-яким шляхом без запису в\nсписку, тож ",[21,276,277],{},"https:\u002F\u002Fyourapp.com\u002Fwelcome"," працює, щойно Site URL правильна.",[10,280,281,284,285,288,289,292,293,296],{},[42,282,283],{},"Додайте інші адреси в Redirect URLs."," Версію з ",[21,286,287],{},"www",", якщо люди нею\nкористуються, опубліковану адресу в білдері (",[21,290,291],{},"https:\u002F\u002Fyourapp.lovable.app",",\nнаприклад), якщо люди там реєструються, і більше нічого. Запис є шаблоном, тож\n",[21,294,295],{},"https:\u002F\u002Fyourapp.com\u002F**"," охоплює кожну сторінку цього одного домену.",[10,298,299,302,303,306,307,309,310,313,314,317],{},[42,300,301],{},"Перевірте, що просить ваш код."," Якщо він передає ",[21,304,305],{},"window.location.origin",",\nадреса буде тією, на якій відкрили сторінку, і кожна адреса, яку це може дати,\nмає лежати на домені вашої Site URL або бути в списку. Порівняйте їх літера в\nлітеру: з ",[21,308,287],{}," чи без, з ",[21,311,312],{},"https"," чи без. Запис без ",[21,315,316],{},"\u002F**"," у кінці збігається\nз цією точною адресою і ні з чим під нею.",[10,319,320,323,324,327,328,330,331,333,334,337],{},[42,321,322],{},"Перевірте шаблони листів."," Шаблон, який сам будує посилання з\n",[21,325,326],{},"{{ .SiteURL }}",", відправляє всіх на Site URL, хоч би що попросив ваш\nзастосунок. Посібник Supabase з перенаправлень каже, що з опцією ",[21,329,89],{},"\nвам, можливо, доведеться замінити ",[21,332,326],{}," на ",[21,335,336],{},"{{ .RedirectTo }}"," у\nшаблонах листів.",[339,340,341,354],"table",{},[342,343,344],"thead",{},[345,346,347,351],"tr",{},[348,349,350],"th",{},"Що ви бачите",[348,352,353],{},"Що змінити",[355,356,357,369,377,385,396],"tbody",{},[345,358,359,366],{},[360,361,362,363],"td",{},"Кожне посилання відкриває ",[21,364,365],{},"localhost:3000",[360,367,368],{},"Site URL",[345,370,371,374],{},[360,372,373],{},"Посилання відкривають вашу Site URL замість адреси, яку попросив ваш код",[360,375,376],{},"Додайте цю адресу в Redirect URLs, літера в літеру",[345,378,379,382],{},[360,380,381],{},"Робочий домен працює, а опублікована адреса в білдері ні",[360,383,384],{},"Додайте опубліковану адресу в Redirect URLs",[345,386,387,390],{},[360,388,389],{},"Посилання відкриває вашу адресу Supabase з \"No API key found in request\"",[360,391,392,393,395],{},"Додайте ",[21,394,261],{}," до Site URL",[345,397,398,401],{},[360,399,400],{},"Адреса, яку просить ваш застосунок, є в списку, а посилання все одно її ігнорує",[360,402,403,405],{},[21,404,326],{}," у шаблоні листа",[10,407,408,409,411],{},"Потім зареєструйтеся ще раз з адресою, якою ще не користувалися. Лист,\nнадісланий до виправлення зі стандартним посиланням Supabase і відкритий у\nмежах своєї години, тепер приводить на ваш робочий сайт, бо Supabase ще раз\nперевіряє адресу, коли посилання відкривають. Це так, якщо\n",[21,410,36],{}," більше немає у вашому списку.",[47,413,415],{"id":414},"які-redirect-urls-безпечно-дозволяти","Які Redirect URLs безпечно дозволяти?",[10,417,418],{},"Точні адреси, які належать вам. Маска доречна для деплоїв попереднього\nперегляду, і лише обмежена вашою командою чи проєктом.",[10,420,421,422,425],{},"Посібник Supabase з перенаправлень каже це прямо: \"globstar\" (",[21,423,424],{},"**",") корисний для\nлокальної розробки й адрес попереднього перегляду, але в продакшні він радить\nзадавати точний шлях перенаправлення для вашої Site URL.",[10,427,428,429,434,435,438],{},"Причина в тому, що мандрує разом із людиною. У типовому потоці Supabase записує\nнову сесію в адресу, куди її відправляє:\n",[58,430,433],{"href":431,"rel":432},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fauth\u002Fblob\u002Fmaster\u002Finternal\u002Ftokens\u002Fservice.go",[62],"код, який її будує",",\nдописує ",[21,436,437],{},"#access_token=…&refresh_token=…"," до адреси перенаправлення. Будь-яка\nсторінка за цією адресою може прочитати ці два значення, і з ними вона стає цим\nкористувачем. На дороговказі саме стрілка вирішує, хто отримає ключ.",[10,440,441],{},"Тож запис, що підходить до адреси, яку контролює хтось інший, стає входом в\nоблікові записи ваших користувачів. Будь-хто може попросити ваш проєкт надіслати\nодному з ваших користувачів посилання для входу, скориставшись публічним\nключем, який стоїть у вашому застосунку навмисно, і вказати свою сторінку як\nмісце призначення. Лист, що приходить, справді від вашого застосунку. Потік\nPKCE цього не змінює, бо людина, яка написала це посилання, сама почала вхід, а\nPKCE віддає сесію тому, хто його почав.",[10,443,444],{},"Шаблони, що підходять до адрес, які можуть створити інші:",[187,446,447,455,466],{},[136,448,449,454],{},[42,450,451,453],{},[21,452,424],{}," сам по собі"," підходить до будь-якої адреси, яка існує.",[136,456,457,462,463,72],{},[42,458,459],{},[21,460,461],{},"https:\u002F\u002F*.vercel.app\u002F**"," підходить до кожного деплою Vercel в\nінтернеті, а створити такий може будь-хто. Власний приклад Supabase містить\nвашу команду: ",[21,464,465],{},"https:\u002F\u002F*-\u003Cteam-or-account-slug>.vercel.app\u002F**",[136,467,468,477,478,72],{},[42,469,470,473,474],{},[21,471,472],{},"https:\u002F\u002F*.lovable.app\u002F**",", ",[21,475,476],{},"https:\u002F\u002F*.netlify.app\u002F**"," і та сама форма на\nдомені будь-якого білдера роблять те саме для цього білдера. Приклад Supabase\nдля Netlify теж обмежений: ",[21,479,480],{},"https:\u002F\u002F**--my_org.netlify.app\u002F**",[167,482],{"alt":483,"caption":484,"src":485},"Два дороговкази. Ліворуч у списку одна точна адреса, підроблене посилання, що вказує деінде, відхилено, і людина приходить до власного будинку з ключем. Праворуч у списку маска, підроблене посилання прийнято, і ключ іде до іншого будинку з червоним контуром.","Точний запис відсилає підроблене посилання додому. Маска, що підходить до чужих застосунків, дозволяє йому доставити їм вхід.","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fwho-gets-the-key-1600x760.png",[10,487,488],{},"Якщо ви щойно розвʼязали це, вставивши маску, перегляньте список ще сьогодні.",[10,490,491,492,72],{},"Запуск також стає моментом, коли переглядають інші налаштування, що важать лише в\nпродакшні. Наше безкоштовне сканування читає ваш робочий застосунок ззовні й\nпоказує, до чого може дістатися незнайомець: таблиці, які відповідають\nбудь-кому, секретні ключі в коді, який надсилає ваш застосунок, відсутні\nзаголовки, сертифікат. Воно триває близько 20 секунд і не потребує облікового\nзапису: ",[58,493,495],{"href":494},"\u002Fsecurity-scanner","проскануйте свій застосунок",[47,497,499],{"id":498},"стежити-за-робочим-застосунком-після-запуску","Стежити за робочим застосунком після запуску",[10,501,502],{},"Це налаштування виправляють один раз. Те, що ваш застосунок надсилає\nвідвідувачам, змінюється з кожним деплоєм, і за цією частиною можна стежити\nззовні.",[10,504,505],{},[42,506,507,511],{},[58,508,510],{"href":509},"\u002Fwebsite-monitoring","Reeve Monitor"," і далі перевіряє ваш робочий застосунок:",[187,513,514,517,520,523],{},[136,515,516],{},"чи він доступний, кожні 60 секунд, щоб \"посилання не працює\" можна було відрізнити від \"сайт лежить\"",[136,518,519],{},"усі девʼять перевірок щогодини, до трьох застосунків, разом із секретними ключами в коді, який ваш застосунок надсилає відвідувачам",[136,521,522],{},"повідомлення, коли результат змінюється, щоб проблема, яка пішла з пізнішим деплоєм, дійшла до вас без того, щоб ви самі йшли дивитися",[136,524,525],{},"щомісячний звіт простою мовою про те, що він бачив",[10,527,528],{},[42,529,530,534],{},[58,531,533],{"href":532},"\u002Fsupabase-backups","Reeve Care"," тримає копію вашої бази даних Supabase разом\nз обліковими записами:",[187,536,537,540,543,546,549,552],{},[136,538,539],{},"зашифрована копія за розкладом, у власному сховищі Reeve в ЄС, поза вашим обліковим записом Supabase",[136,541,542],{},"схема auth, де живуть облікові записи ваших користувачів, щоб вони повернулися разом з усім іншим",[136,544,545],{},"кожна копія перевірена, перш ніж зарахуватися, підрахунком рядків у кожній таблиці",[136,547,548],{},"ваші вивантажені файли теж, щойно ви підключите доступ до Storage",[136,550,551],{},"відновлення в один клік, із безпечною копією поточного стану, зробленою заздалегідь",[136,553,554],{},"усе, що робить Monitor",[47,556,558],{"id":557},"що-зробити-зараз","Що зробити зараз",[560,561,562],"key-takeaways",{},[187,563,564,569,575,587,590],{},[136,565,566,567,72],{},"Поставте в Site URL на сторінці URL Configuration свою робочу адресу разом з ",[21,568,261],{},[136,570,571,572,574],{},"Додайте в Redirect URLs інші точні адреси, куди ви відправляєте людей, наприклад версію з ",[21,573,287],{}," і опубліковану адресу в білдері.",[136,576,577,578,580,581,583,584,586],{},"Переконайтеся, що кожна адреса, яку ваш код передає як ",[21,579,106],{}," чи ",[21,582,89],{},", є в списку, і використовуйте ",[21,585,336],{}," у шаблонах, які мають за нею йти.",[136,588,589],{},"Скажіть усім, хто після реєстрації побачив сторінку localhost, що їхній обліковий запис підтверджений. Magic links і скидання пароля потребують нового листа.",[136,591,592],{},"Залиште маски лише для попереднього перегляду вашої команди й ніколи не дозволяйте всі застосунки на домені білдера.",[10,594,595,596,599,600,604],{},"Якщо люди натискають нове посилання і чують, що воно прострочене,\n",[58,597,598],{"href":234},"для цього повідомлення є окрема сторінка",".\n",[58,601,603],{"href":602},"\u002Fchecklist","10-хвилинний чекліст безпеки"," охоплює те, що зазвичай лишається\nвідкритим у щойно запущеному застосунку.",{"title":23,"searchDepth":606,"depth":606,"links":607},3,[608,610,611,612,613,614,615,616],{"id":49,"depth":609,"text":50},2,{"id":96,"depth":609,"text":97},{"id":181,"depth":609,"text":182},{"id":218,"depth":609,"text":219},{"id":241,"depth":609,"text":242},{"id":414,"depth":609,"text":415},{"id":498,"depth":609,"text":499},{"id":557,"depth":609,"text":558},"Основи безпеки","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcover-1200x630.png","Дороговказ, чия освітлена стрілка показує геть від будинку, до якого має вести, у бік ноутбука з темним екраном.","Якщо Supabase перенаправляє на localhost:3000, Site URL так і не змінили або вашої адреси немає в Redirect URLs. Як виправити і якої маски уникати.",false,"md",[624,627,630,633,636],{"q":625,"a":626},"Чому лист підтвердження від Supabase відкриває localhost:3000?","Тому що Supabase відправив людину на Site URL вашого проєкту, а Site URL досі http:\u002F\u002Flocalhost:3000. Supabase бере її щоразу, коли адреси, яку попросив ваш застосунок, немає у списку Redirect URLs або коли застосунок не попросив жодної. Змініть її на сторінці URL Configuration у розділі Authentication.",{"q":628,"a":629},"Чи підтверджений обліковий запис, якщо посилання відкрило localhost?","Так, якщо це підтвердження реєстрації. Supabase спершу підтверджує адресу і лише потім відправляє браузер далі, тож сторінка, що не відкрилася, зʼявляється, коли роботу вже зроблено. Людина може увійти на вашому робочому сайті з паролем, який обрала. Magic link чи скидання пароля треба надіслати заново.",{"q":631,"a":632},"Я додав свій сайт у Redirect URLs, а посилання досі веде на localhost. Чому?","Запис має збігатися з адресою, яку пропонують Supabase, літера в літеру: з www чи без, з https чи без, і шлях, бо запис без \u002F** у кінці збігається лише з цією однією адресою. Якщо вони збігаються, а посилання все одно її ігнорує, ваш шаблон листа будує посилання з {{ .SiteURL }}. І виправте саму Site URL, бо до неї повертається все інше.",{"q":634,"a":635},"Чи треба додавати Site URL у список Redirect URLs?","Ні. Supabase приймає будь-яку адресу на домені самої Site URL без запису в списку, з будь-яким шляхом. Список потрібен для інших адрес: версії з www, опублікованої адреси в білдері, деплоїв попереднього перегляду.",{"q":637,"a":638},"Чи можна використати маску в Redirect URLs у Supabase?","Для попереднього перегляду, обмежену вашою командою чи проєктом, як у прикладах самого Supabase. Ніколи таку, що підходить до адрес, які можуть створити інші, наприклад до всіх застосунків на vercel.app чи lovable.app. Для сайту в продакшні Supabase радить точну адресу.","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",[641,642,643,644,645,646,647],"supabase redirect to localhost","supabase перенаправляє на localhost","supabase magic link localhost 3000","supabase site url","supabase redirect urls","лист підтвердження supabase неправильна адреса","supabase redirect url маска",{},true,"Supabase перенаправляє посилання з листів на localhost:3000","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","2026-11-02",{"title":5,"description":620},"blog\u002Fsupabase-auth-redirects-to-localhost",[656,657,658],"Перенаправлення Supabase на localhost:3000 іде від Site URL на сторінці URL Configuration. Проєкт починає з http:\u002F\u002Flocalhost:3000, і кожне посилання з листа повертається до неї, коли адреси, яку попросив ваш застосунок, немає у списку Redirect URLs.","Той, хто натиснув посилання з реєстрації, зазвичай уже підтверджений. Supabase підтверджує обліковий запис, перш ніж відправити людину далі, тож вона може увійти на вашому справжньому сайті.","Поставте в Site URL свою робочу адресу й внесіть у список точні адреси, якими користуєтеся. Маска, настільки широка, що підходить до чужого застосунку, дозволяє підробленому посиланню відправити туди ваших користувачів уже з виконаним входом.","weUSaCKHYgkUmBmj9J0iq33WQx39re89nHQXnTYMVWk",[661,667,672,678,684,690,696,702,703,708,714,721,727,733,739,745,751,757,763,769,775,781,787,793,799,805,811,817,823,829,835,841,847,853,858,864,870,876,882,888,894,900,906,912,918,924,929,935,941,947,953,959,965,971,977,983,989,995,1001,1007,1013,1019,1025,1031,1037,1043,1049,1055,1061,1067,1073,1079,1085,1091,1097,1103,1109,1115,1121,1127,1133,1139,1145,1151,1156,1162,1168,1174,1179,1185],{"path":662,"title":663,"description":664,"published":665,"category":617,"image":666,"draft":621},"\u002Fblog\u002Fmax-client-connections-reached","Supabase \"max client connections reached\": пояснення","Supabase \"max client connections reached\": у пулера немає місця ще для одного клієнта. Ліміт визначає порт у вашому рядку підключення.","2026-11-09","\u002Fblog\u002Fmax-client-connections-reached\u002Fcard-800x500.png",{"path":177,"title":668,"description":669,"published":670,"category":617,"image":671,"draft":621},"Помилка Supabase: \"Unsupported provider: provider is not enabled\"","\"Unsupported provider: provider is not enabled\": вхід через Google вимкнено у вашому проєкті Supabase. Як увімкнути та виправити redirect_uri_mismatch.","2026-11-08","\u002Fblog\u002Funsupported-provider-provider-is-not-enabled\u002Fcard-800x500.png",{"path":673,"title":674,"description":675,"published":676,"category":617,"image":677,"draft":621},"\u002Fblog\u002Fviolates-foreign-key-constraint","Помилка Supabase \"violates foreign key constraint\" під час вставки","Supabase \"insert or update on table violates foreign key constraint\": ваш рядок посилається на рядок, якого немає. Який, чому і як це виправити.","2026-11-07","\u002Fblog\u002Fviolates-foreign-key-constraint\u002Fcard-800x500.png",{"path":679,"title":680,"description":681,"published":682,"category":617,"image":683,"draft":621},"\u002Fblog\u002Fnull-value-violates-not-null-constraint","Помилка Supabase \"null value in column violates not-null constraint\"","Supabase \"null value in column violates not-null constraint\": обовʼязковий стовпець прийшов порожнім. Звідки взявся null і як це виправити.","2026-11-06","\u002Fblog\u002Fnull-value-violates-not-null-constraint\u002Fcard-800x500.png",{"path":685,"title":686,"description":687,"published":688,"category":617,"image":689,"draft":621},"\u002Fblog\u002Fauth-session-missing","Supabase \"Auth session missing!\": куди поділася сесія","\"Auth session missing!\" означає, що supabase-js не знайшла жодної сесії й навіть не спитала Supabase. Куди поділася сесія і як це виправити.","2026-11-05","\u002Fblog\u002Fauth-session-missing\u002Fcard-800x500.png",{"path":691,"title":692,"description":693,"published":694,"category":617,"image":695,"draft":621},"\u002Fblog\u002Finvalid-claim-missing-sub-claim","Supabase \"invalid claim: missing sub claim\": ніхто не ввійшов","\"invalid claim: missing sub claim\": Supabase Auth отримав справжній токен без жодного користувача, ключ проєкту замість сесії.","2026-11-04","\u002Fblog\u002Finvalid-claim-missing-sub-claim\u002Fcard-800x500.png",{"path":697,"title":698,"description":699,"published":700,"category":617,"image":701,"draft":621},"\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function","\"Failed to send a request to the Edge Function\": справжня причина","\"Failed to send a request to the Edge Function\": браузер не отримав відповіді, яку можна прочитати. Його консоль каже, чому, і чи ваша функція запускалася.","2026-11-03","\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function\u002Fcard-800x500.png",{"path":651,"title":5,"description":620,"published":652,"category":617,"image":639,"draft":621},{"path":234,"title":704,"description":705,"published":706,"category":617,"image":707,"draft":621},"Supabase \"Email link is invalid or has expired\" на новому посиланні","На посиланні, надісланому хвилину тому, \"Email link is invalid or has expired\" у Supabase зазвичай означає, що поштовий фільтр використав його першим.","2026-11-01","\u002Fblog\u002Femail-link-is-invalid-or-has-expired\u002Fcard-800x500.png",{"path":709,"title":710,"description":711,"published":712,"category":617,"image":713,"draft":621},"\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout","Supabase \"canceling statement due to statement timeout\": пояснення","Supabase \"canceling statement due to statement timeout\": запит перевищив ліміт своєї ролі, 3 секунди для відвідувача. Спершу перевірте політику RLS.","2026-10-31","\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout\u002Fcard-800x500.png",{"path":715,"title":716,"description":717,"published":718,"category":719,"image":720,"draft":621},"\u002Fblog\u002Fdatabase-error-deleting-user","\"Database error deleting user\" у Supabase і що зникає разом","\"Database error deleting user\" у Supabase: ваша база відмовилася видаляти. Причина в логах, а виправлення вирішує, що ще буде видалено.","2026-10-30","Backups","\u002Fblog\u002Fdatabase-error-deleting-user\u002Fcard-800x500.png",{"path":722,"title":723,"description":724,"published":725,"category":617,"image":726,"draft":621},"\u002Fblog\u002Fstripe-webhook-no-signatures-found","\"No signatures found matching the expected signature\" у Supabase","Вебхук Stripe в Edge Function Supabase пише \"No signatures found matching the expected signature\"? Причин дві. Не вимикайте перевірку.","2026-10-29","\u002Fblog\u002Fstripe-webhook-no-signatures-found\u002Fcard-800x500.png",{"path":728,"title":729,"description":730,"published":731,"category":617,"image":732,"draft":621},"\u002Fblog\u002Fsupabase-invalid-login","\"Invalid login credentials\" у Supabase: три причини","Supabase відповідає \"Invalid login credentials\" на неправильний пароль, невідому пошту й акаунт Google. Як зрозуміти, що саме.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":734,"title":735,"description":736,"published":737,"category":617,"image":738,"draft":621},"\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code","\"Edge Function returned a non-2xx status code\": справжня помилка","\"Edge Function returned a non-2xx status code\" означає, що ваша функція Supabase відповіла помилкою. Ось де прочитати справжню.","2026-10-27","\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code\u002Fcard-800x500.png",{"path":740,"title":741,"description":742,"published":743,"category":617,"image":744,"draft":621},"\u002Fblog\u002Fcertificate-not-trusted","Сертифікат не довірений: три причини, крім закінчення строку","Сертифікат не довірений, хоча дата в порядку? Він називає іншу адресу, підписав сам себе або в його ланцюжку бракує ланки. Як зрозуміти, що саме.","2026-10-26","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",{"path":746,"title":747,"description":748,"published":749,"category":617,"image":750,"draft":621},"\u002Fblog\u002Finvalid-input-syntax-for-type-uuid","Supabase \"invalid input syntax for type uuid\": що в лапках","Supabase \"invalid input syntax for type uuid\" означає, що застосунок надіслав щось, що не є id. Прочитайте лапки, притримайте запит, залиште колонку.","2026-10-25","\u002Fblog\u002Finvalid-input-syntax-for-type-uuid\u002Fcard-800x500.png",{"path":752,"title":753,"description":754,"published":755,"category":617,"image":756,"draft":621},"\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint","Supabase \"duplicate key value violates unique constraint\": пояснення","Supabase \"duplicate key value violates unique constraint\": значення вже зайняте. Знайдіть стовпець, оберіть виправлення й сховайте значення від очей.","2026-10-24","\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint\u002Fcard-800x500.png",{"path":758,"title":759,"description":760,"published":761,"category":617,"image":762,"draft":621},"\u002Fblog\u002Fsupabase-relation-does-not-exist","Supabase \"relation does not exist\", хоча таблиця на місці","Supabase \"relation does not exist\" або PGRST205: жодна таблиця не має такої назви в цій схемі. Чотири перевірки, і на що зважити, відкриваючи схему.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":764,"title":765,"description":766,"published":767,"category":617,"image":768,"draft":621},"\u002Fblog\u002Fsupabase-function-not-found","Supabase PGRST202: \"Could not find the function in the schema cache\"","Supabase \"Could not find the function in the schema cache\" показує назви аргументів, які надіслав ваш застосунок. Порівняйте їх із функцією.","2026-10-22","\u002Fblog\u002Fsupabase-function-not-found\u002Fcard-800x500.png",{"path":770,"title":771,"description":772,"published":773,"category":617,"image":774,"draft":621},"\u002Fblog\u002Fsupabase-schema-cache-column-error","Supabase PGRST204: \"Could not find the column in the schema cache\"","Supabase \"Could not find the column in the schema cache\" зазвичай означає, що назва не збігається. Чотири перевірки і рядок для перезавантаження.","2026-10-21","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",{"path":776,"title":777,"description":778,"published":779,"category":617,"image":780,"draft":621},"\u002Fblog\u002Fsupabase-email-rate-limit-exceeded","Supabase \"Email Rate Limit Exceeded\": два ліміти, один код помилки","Supabase \"Email Rate Limit Exceeded\" обмежує кожен лист вашого проєкту: 2 на годину з вбудованим відправником. Що враховується і як підняти ліміт.","2026-10-20","\u002Fblog\u002Fsupabase-email-rate-limit-exceeded\u002Fcard-800x500.png",{"path":782,"title":783,"description":784,"published":785,"category":617,"image":786,"draft":621},"\u002Fblog\u002Fsupabase-users-logged-out","Supabase \"Invalid Refresh Token: Refresh Token Not Found\": 3 причини","Supabase \"Invalid Refresh Token: Refresh Token Not Found\" виводить ваших користувачів із системи. Три причини і як лог Auth їх розрізняє.","2026-10-19","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcard-800x500.png",{"path":788,"title":789,"description":790,"published":791,"category":617,"image":792,"draft":621},"\u002Fblog\u002Fpermission-denied-for-schema-public","Supabase \"permission denied for schema public\": три причини","Supabase \"permission denied for schema public\" означає, що бракує GRANT на схему. Що його прибрало і який рядок його повертає.","2026-10-18","\u002Fblog\u002Fpermission-denied-for-schema-public\u002Fcard-800x500.png",{"path":794,"title":795,"description":796,"published":797,"category":617,"image":798,"draft":621},"\u002Fblog\u002Fsupabase-bucket-not-found","Supabase \"Bucket not found\": три речі, які це може означати","Supabase \"Bucket not found\" означає одне з трьох: публічне посилання на приватний бакет, неточну назву або не той проєкт.","2026-10-17","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",{"path":800,"title":801,"description":802,"published":803,"category":617,"image":804,"draft":621},"\u002Fblog\u002Fsupabase-invalid-jwt","Supabase invalid JWT: який ключ перестав працювати?","Помилка Supabase invalid JWT — це PGRST301: підписаний токен не пройшов перевірку. У новому проєкті йдеться про сесію, а не про ключ API.","2026-10-16","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",{"path":806,"title":807,"description":808,"published":809,"category":617,"image":810,"draft":621},"\u002Fblog\u002Fsupabase-single-row-error","Supabase \"multiple (or no) rows returned\" майже завжди означає нуль","Supabase повертає PGRST116, \"JSON object requested, multiple (or no) rows returned\", коли запит нічого не знайшов. Прихований рядок має вигляд відсутнього.","2026-10-15","\u002Fblog\u002Fsupabase-single-row-error\u002Fcard-800x500.png",{"path":812,"title":813,"description":814,"published":815,"category":617,"image":816,"draft":621},"\u002Fblog\u002Fdatabase-error-saving-new-user","\"Database error saving new user\" у Supabase: де шукати","\"Database error saving new user\" означає, що щось причеплене до вашої реєстрації в Supabase впало. Справжня помилка лежить у ваших логах.","2026-10-14","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcard-800x500.png",{"path":818,"title":819,"description":820,"published":821,"category":617,"image":822,"draft":621},"\u002Fblog\u002Fwhat-is-supabase","Що таке Supabase? База даних, яку обрав ваш білдер","Що таке Supabase: база даних, вхід і сховище файлів за вашим застосунком. Supabase тримає сервери, а правила про те, хто читає ваші рядки, ваші.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":824,"title":825,"description":826,"published":827,"category":617,"image":828,"draft":621},"\u002Fblog\u002Faws-access-key-exposed-in-frontend","Відкритий у фронтенді ключ AWS це не те саме, що ключ OpenAI","Ключ доступу AWS, відкритий у вашому фронтенді, читає і пише ваше сховище. Рішення зазвичай presigned URL, а не новий ключ.","2026-10-12","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":830,"title":831,"description":832,"published":833,"category":617,"image":834,"draft":621},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" при вивантаженні","\"New row violates row-level security policy for table objects\" означає, що вашому вивантаженню бракує правила insert. Публічний бакет його не додає.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":836,"title":837,"description":838,"published":839,"category":617,"image":840,"draft":621},"\u002Fblog\u002Fbase44-security-scan","Сканування безпеки Base44: те, що бачить лише воно","Сканування безпеки Base44 перевіряє сім видів проблем зсередини. Ось половина, яку читає тільки воно, і половина, на яку воно ніколи не дивиться.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":842,"title":843,"description":844,"published":845,"category":617,"image":846,"draft":621},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Ваш API-ключ витік. Порядок дій","API-ключ витік, і ви не знаєте, що робити першим. Не кожен ключ у вашому фронтенді є витоком, а порядок важить більше за швидкість.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":848,"title":849,"description":850,"published":851,"category":617,"image":852,"draft":621},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" без вимкнення RLS","\"Infinite recursion detected in policy for relation\" означає, що ваша policy запитала таблицю, яку вона захищає. Ось як розірвати коло.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":272,"title":854,"description":855,"published":856,"category":617,"image":857,"draft":621},"\"No API key found in request\" у Supabase, і хибне виправлення","\"No API key found in request\" означає, що запит дійшов до Supabase без ключа. Більшість відповідей натомість вказують на правила вашої бази.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":859,"title":860,"description":861,"published":862,"category":617,"image":863,"draft":621},"\u002Fblog\u002Fis-base44-safe","Чи безпечний Base44? Дані 5 442 застосунків","Чи безпечний Base44? Ми прогнали дев’ять перевірок на 5 442 робочих застосунках Base44. Майже всі отримали B з причин, яких власник ніколи не обирав.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":865,"title":866,"description":867,"published":868,"category":617,"image":869,"draft":621},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","Сховати ключ API: перенесіть його в Supabase Edge Function","Сховати ключ API означає прибрати його з браузера, а Supabase Edge Function це найменше місце, куди його покласти. Два кроки поруч важать більше.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":871,"title":872,"description":873,"published":874,"category":617,"image":875,"draft":621},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Чи відкритий ваш файл .env? Дванадцять шляхів для перевірки","Чи відкритий ваш файл .env на вашому власному вебсервері? Дванадцять адрес скажуть це за хвилину, а влучання означає, що все в ньому вже публічне.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":877,"title":878,"description":879,"published":880,"category":617,"image":881,"draft":621},"\u002Fblog\u002Fis-v0-safe","Безпека v0: усі 1 790 просканованих застосунків v0 отримали A","Безпека v0 на 1 790 живих застосунках v0: усі отримали A. Лише 17 згадували базу даних, і саме це здебільшого вимірює оцінка A.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":883,"title":884,"description":885,"published":886,"category":617,"image":887,"draft":621},"\u002Fblog\u002Fis-bolt-safe","Чи безпечний Bolt? Що показали 1 123 застосунки Bolt","Чи безпечний Bolt? Ми прогнали 1 123 живі застосунки Bolt через дев’ять перевірок. Хостинг був чистим. Знахідки: ключі й відкриті таблиці в самих застосунках.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":889,"title":890,"description":891,"published":892,"category":617,"image":893,"draft":621},"\u002Fblog\u002Fis-supabase-down-or-your-app","Supabase не працює чи проблема у вашому застосунку? Як розрізнити","Supabase не працює чи зламався ваш застосунок? Пауза, повна база й ваша власна помилка виглядають однаково. Чотири перевірки їх розрізняють.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":895,"title":896,"description":897,"published":898,"category":617,"image":899,"draft":621},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","Чи шифрує Supabase мої дані? Так. Ось від чого це захищає","Чи шифрує Supabase дані? Так: AES-256 у стані спокою, TLS під час передавання, SOC 2 та ISO 27001. Що покриває кожне і який витік не зупиняє жодне.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":901,"title":902,"description":903,"published":904,"category":617,"image":905,"draft":621},"\u002Fblog\u002Fsupabase-free-plan-limits","Ліміти безкоштовного тарифу Supabase і що стається на кожному","Ліміти безкоштовного тарифу Supabase: 500 МБ бази, 5 ГБ egress і жодних резервних копій. Що стається на кожній межі і що змінює Pro за $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":907,"title":908,"description":909,"published":910,"category":719,"image":911,"draft":621},"\u002Fblog\u002Ftest-your-supabase-backup","Перевірте резервну копію Supabase до того, як вона знадобиться","Як перевірити резервну копію Supabase: відновити в тестовий проєкт, порахувати рядки, увійти й знайти рядок, якого бракує обрізаному файлу.","2026-09-28","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":913,"title":914,"description":915,"published":916,"category":719,"image":917,"draft":621},"\u002Fblog\u002Fsupabase-backup-github-action","Безкоштовна резервна копія Supabase через GitHub Action і підступ","Резервна копія Supabase через GitHub Action безкоштовна й годиться багатьом застосункам. Робочий процес, потрібний рядок підключення та egress.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":919,"title":920,"description":921,"published":922,"category":719,"image":923,"draft":621},"\u002Fblog\u002Fdownload-your-supabase-backup","Чому ви не можете завантажити резервну копію Supabase","Завантажити резервну копію Supabase на сучасному проєкті не вийде: щоденна копія там фізична. Як це перевірити і як тримати власну копію.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":925,"title":926,"description":927,"published":922,"category":617,"image":928,"draft":621},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": бракує GRANT","З 30 жовтня нова таблиця в Supabase відповідає \"permission denied for table\", доки ви не дасте доступ. Лист показує лише половину виправлення.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":930,"title":931,"description":932,"published":933,"category":617,"image":934,"draft":621},"\u002Fblog\u002Fopen-api-endpoint-exposed","Чи є відкритий API-ендпоінт проблемою безпеки? Читайте JSON","Ваше сканування позначило відкритий API-ендпоінт. Чи це важливо, залежить від того, що повернулося, і більшість знайдених належали платформі.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":936,"title":937,"description":938,"published":939,"category":617,"image":940,"draft":621},"\u002Fblog\u002Flovable-security-scan","Сканування безпеки Lovable: чого воно не доведе","Сканування безпеки Lovable: що перевіряють Quick scan і Deep scan, коли запускається кожне, і єдине, чого не доведе жодне сканування зсередини.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":942,"title":943,"description":944,"published":945,"category":719,"image":946,"draft":621},"\u002Fblog\u002Fsupabase-backup-auth-users","Чому у вашому дампі Supabase немає користувачів","Запустіть supabase db dump окремо і отримаєте форму вашої бази та жодного її рядка, без схеми auth, у якій живуть ваші користувачі.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":948,"title":949,"description":950,"published":951,"category":617,"image":952,"draft":621},"\u002Fblog\u002Fdomain-and-certificate-expiry","Домен закінчився, сайт лежить: що буде далі","Ваш домен закінчився і сайт лежить. Ось який годинник уже пішов, чому прострочений сертифікат це менша з двох бід, і як перевірити обидва.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":954,"title":955,"description":956,"published":957,"category":617,"image":958,"draft":621},"\u002Fblog\u002Fis-lovable-safe","Чи безпечний Lovable? Що показали 18 554 застосунки Lovable","Чи безпечний Lovable? Ми прогнали 18 554 живі застосунки Lovable через дев’ять перевірок. Платформа виявилася найчистішою з п’яти. Знахідки були в застосунках.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":960,"title":961,"description":962,"published":963,"category":617,"image":964,"draft":621},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Чек-лист безпеки для vibe coding, у девʼяти перевірках","Чек-лист безпеки для vibe coding із девʼяти пунктів, кожен з яких будь-хто може перевірити у вашому живому застосунку ззовні, і кожен має тест на один рядок.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":966,"title":967,"description":968,"published":969,"category":617,"image":970,"draft":621},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Секретний ключ Stripe у фронтенді може рухати гроші","Секретний ключ Stripe, відкритий у вашому фронтенді, може повертати кошти, списувати й читати кожну картку клієнта. А ключ pk_live_ там і має бути.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":972,"title":973,"description":974,"published":975,"category":617,"image":976,"draft":621},"\u002Fblog\u002Fvite-and-next-public-env-vars","Змінні оточення Vite відкриті: префікс означає опублікувати це","Змінні оточення Vite відкриті у вашому застосунку, бо так просив префікс. VITE_ і NEXT_PUBLIC_ означають опублікувати це, а ШІ, який їх додав, не знав ціни.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":978,"title":979,"description":980,"published":981,"category":617,"image":982,"draft":621},"\u002Fblog\u002Fbase44-source-maps","Безпека Base44: що позначає скан і що з цього виправляти вам","Безпека Base44 на 5 438 просканованих застосунках: три знахідки майже на кожному належать платформі, source map є бейджем Base44, а ваша частина коротка.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":984,"title":985,"description":986,"published":987,"category":617,"image":988,"draft":621},"\u002Fblog\u002Fis-cursor-ai-safe","Чи безпечний Cursor AI? Редактор, код і опублікований застосунок","Чи безпечний Cursor AI? Три запитання в одному пошуку: що Cursor зберігає, у чому помиляється його код і чи відкритий застосунок, який ви опублікували.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":990,"title":991,"description":992,"published":993,"category":617,"image":994,"draft":621},"\u002Fblog\u002Fis-replit-safe","Чи безпечний Replit? Що ми знайшли в 3 042 живих застосунках Replit","Чи безпечний Replit? Ми прогнали 3 042 живі застосунки Replit через дев’ять зовнішніх перевірок. Знахідки були в опублікованому застосунку, а не в хостингу.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":996,"title":997,"description":998,"published":999,"category":719,"image":1000,"draft":621},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: у копії бази даних немає жодного файлу","Supabase storage backup це окрема робота. Копії бази даних зберігають список ваших файлів і жодного з них, тож після відновлення кожне завантаження зламане.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":1002,"title":1003,"description":1004,"published":1005,"category":719,"image":1006,"draft":621},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery у Supabase: ціна та межі","Point-in-time recovery у Supabase відмотує базу на будь-яку секунду за останній тиждень. Коштує $100 на місяць понад Pro і покриває лише базу даних.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":1008,"title":1009,"description":1010,"published":1011,"category":719,"image":1012,"draft":621},"\u002Fblog\u002Fsupabase-project-paused-recover","Проєкт Supabase на паузі? Ваші дані нікуди не зникли","Supabase поставив ваш проєкт на паузу після тижня без активності. Нічого не видалено, кнопка Restore стоїть поруч із назвою, і у вас є рік, щоб натиснути.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":1014,"title":1015,"description":1016,"published":1017,"category":617,"image":1018,"draft":621},"\u002Fblog\u002Fsafest-ai-app-builder","Який білдер застосунків з ШІ найбезпечніший? 30 998 тестів","Який білдер застосунків з ШІ найбезпечніший? Ми просканували 30 998 живих застосунків з Lovable, Base44, Replit, v0 і Bolt. Оцінку вирішує не білдер.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":1020,"title":1021,"description":1022,"published":1023,"category":617,"image":1024,"draft":621},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Увімкніть Row Level Security на кожній таблиці Supabase і перевірте","Row Level Security у Supabase без політики закриває таблицю повністю. Політика без увімкненого перемикача не робить нічого. Ось SQL, і ось перевірка.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":1026,"title":1027,"description":1028,"published":1029,"category":617,"image":1030,"draft":621},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": чого не бачить попередження","Supabase позначає \"RLS disabled in public\" як помилку. Про політику читання, яка лишає вашу таблицю так само відкритою, він не каже нічого.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":1032,"title":1033,"description":1034,"published":1035,"category":617,"image":1036,"draft":621},"\u002Fblog\u002Frotate-supabase-service-role-key","Як замінити злитий ключ service_role у Supabase","Supabase каже спершу закрити витік. Інші посібники кажуть міняти негайно. Що правильно, залежить від того, куди саме потрапив ваш ключ service_role.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":1038,"title":1039,"description":1040,"published":1041,"category":617,"image":1042,"draft":621},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Сканери безпеки для vibe coding у порівнянні, наш теж","Найкращий сканер безпеки для vibe coding залежить від трьох питань, на які не відповідає жоден перелік функцій. Вісім інструментів і ціни.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":1044,"title":1045,"description":1046,"published":1047,"category":617,"image":1048,"draft":621},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: п’ять перевірок, які зробите самі","Supabase security checker читає ваш опублікований застосунок, а не налаштування проєкту. Ось п’ять перевірок і як виконати кожну самостійно.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":1050,"title":1051,"description":1052,"published":1053,"category":617,"image":1054,"draft":621},"\u002Fblog\u002Fvibe-coding-security-scanner","Сканер безпеки для vibe coding: чого не бачить скан URL","Сканер безпеки для vibe coding читає ваш робочий застосунок ззовні. Що це охоплює, чотири речі, яких він не бачить, і як читати результат.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":1056,"title":1057,"description":1058,"published":1059,"category":617,"image":1060,"draft":621},"\u002Fblog\u002Fmissing-security-headers","Відсутні заголовки безпеки: коли це справді важливо","Відсутні заголовки безпеки трапляються в наших звітах найчастіше. Від чого вони захищають і коли це найменш терміновий рядок вашого звіту.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":1062,"title":1063,"description":1064,"published":1065,"category":617,"image":1066,"draft":621},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Ваш ключ API OpenAI відкритий у фронтенді. Замініть його.","Ключ API OpenAI, відкритий у фронтенді, не можна прив'язати до домену. Замініть його сьогодні, перенесіть виклик на свій сервер і обмежте витрати.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1068,"title":1069,"description":1070,"published":1071,"category":617,"image":1072,"draft":621},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Ключ API у фронтенді: що насправді віддають 30 998 застосунків","Ключ API, відкритий у вашому фронтенді, зазвичай є ключем Google Maps. Ми просканували 30 998 vibe-coded застосунків і порахували, що витікає насправді.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":1074,"title":1075,"description":1076,"published":1077,"category":719,"image":1078,"draft":621},"\u002Fblog\u002Fsupabase-backup-tools-compared","Інструменти резервного копіювання Supabase, і наш серед них","Чотири види інструментів резервного копіювання Supabase, що копіює кожен і коли безкоштовна GitHub Action виграє в будь-якої оплати, нашої теж.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":1080,"title":1081,"description":1082,"published":1083,"category":617,"image":1084,"draft":621},"\u002Fblog\u002Freplit-secrets-explained","Як користуватися секретами в Replit і що все одно публікується","Як користуватися секретами в Replit: додати, прочитати і усунути дві причини undefined. А ще ключі, які цей інструмент не здатен зберегти в таємниці.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":1086,"title":1087,"description":1088,"published":1089,"category":719,"image":1090,"draft":621},"\u002Fblog\u002Fback-up-supabase-free-tier","Резервні копії на безкоштовному тарифі Supabase без терміналу","На безкоштовному тарифі Supabase резервних копій немає: копію робите ви. Як зробити її з панелі та що втрачає шлях через CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":1092,"title":1093,"description":1094,"published":1095,"category":617,"image":1096,"draft":621},"\u002Fblog\u002Fis-supabase-secure","Чи безпечний Supabase? Так. Ваш проєкт це інше питання","Чи безпечний Supabase? Платформа проходить аудити, шифрує дані й тримає пентести. Їхня документація каже, де це закінчується і починаються ваші налаштування.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":1098,"title":1099,"description":1100,"published":1101,"category":617,"image":1102,"draft":621},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Де знайти API-ключі Supabase: anon, service_role і URL","URL проєкту, ключ anon і ключ service_role лежать на одній сторінці панелі. Ось де вона, і яке з чотирьох значень має бути у вашому застосунку.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":1104,"title":1105,"description":1106,"published":1107,"category":617,"image":1108,"draft":621},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy в Supabase. Що далі?","\"New row violates row-level security policy\" означає, що Supabase відмовив у записі. Швидке виправлення знову відкриває таблицю для всіх.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":1110,"title":1111,"description":1112,"published":1113,"category":617,"image":1114,"draft":621},"\u002Fblog\u002Fcors-wildcard-security-risk","Чи є вайлдкард CORS ризиком для безпеки? Майже ніколи.","Чи є вайлдкард CORS ризиком для безпеки? Зазвичай це типове налаштування вашого білдера, і воно не видає нічого, що ваш сервер і так віддавав кожному.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":1116,"title":1117,"description":1118,"published":1119,"category":719,"image":1120,"draft":621},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Branching у Supabase це не бекап. Він іде тільки вперед.","Чому branching у Supabase це не бекап: гілка стартує без ваших даних, а мердж переносить саму лише схему. Для чого він потрібен і що брати замість нього.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":1122,"title":1123,"description":1124,"published":1125,"category":719,"image":1126,"draft":621},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Як відновити резервну копію Supabase, і що ламається потім","Як відновити резервну копію Supabase з панелі або з файлу дампа, що саме замінює відновлення і чому ваш застосунок може лишитися зламаним після нього.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":1128,"title":1129,"description":1130,"published":1131,"category":617,"image":1132,"draft":621},"\u002Fblog\u002Fsupabase-storage-bucket-public","Ваш бакет Supabase Storage публічний. Чи це проблема?","Публічний бакет Supabase Storage означає, що той, хто має URL файлу, може його відкрити. Він не означає, що хтось може переглянути список вмісту.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":1134,"title":1135,"description":1136,"published":1137,"category":617,"image":1138,"draft":621},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Чи є проблемою ключ API Google у вашому браузері?","Ключ API Google у відкритому коді сторінки наш сканер знаходить найчастіше, і зазвичай усе гаразд. Вирішує це одне безкоштовне налаштування.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1140,"title":1141,"description":1142,"published":1143,"category":719,"image":1144,"draft":621},"\u002Fblog\u002Fai-agent-deleted-my-database","ШІ-агент видалив мої дані в Supabase. Що можна відновити?","ШІ-агент видалив дані з вашої бази. Те, що ви зможете відновити, вирішилося раніше, а наступні хвилини вирішують, скільки з цього вціліє.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":1146,"title":1147,"description":1148,"published":1149,"category":617,"image":1150,"draft":621},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Чи може будь-хто прочитати вашу базу Supabase? 3 680 застосунків","Чи може будь-хто прочитати вашу базу даних Supabase без входу? Ми просканували 30 998 живих застосунків, зроблених ШІ-білдерами, і виміряли, як часто так.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":1152,"title":1153,"description":1154,"published":1149,"category":617,"image":1155,"draft":621},"\u002Fblog\u002Fsource-maps-exposed-in-production","Відкриті source maps: ваш застосунок публікує свій вихідний код","Відкрита source map дає будь-кому прочитати оригінальний код вашого застосунку, разом із коментарями. Перевірка за 30 секунд, і що важить насправді.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":1157,"title":1158,"description":1159,"published":1160,"category":617,"image":1161,"draft":621},"\u002Fblog\u002Fsupabase-new-api-keys","Supabase publishable key: це той самий anon key?","Supabase замінив anon і service_role публічними та секретними ключами. Який із них має бути у вашому застосунку, а який не має бути ніколи?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":1163,"title":1164,"description":1165,"published":1166,"category":719,"image":1167,"draft":621},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Чи робить Supabase резервні копії моєї бази? Залежить від тарифу.","Чи робить Supabase резервні копії вашої бази даних? На платних тарифах щодня, на безкоштовному жодної. Як дізнатися, що у вас насправді є.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":1169,"title":1170,"description":1171,"published":1172,"category":617,"image":1173,"draft":621},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security увімкнено. Таблиця досі публічна.","Увімкнути Supabase Row Level Security не означає захистити таблицю. Захищають політики, а та, що полагодила застосунок, часто впускає всіх.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":1175,"title":1176,"description":1177,"published":1172,"category":719,"image":1178,"draft":621},"\u002Fblog\u002Fversion-history-is-not-a-backup","Історія версій не є резервною копією. Вона не поверне таблицю.","Lovable і Bolt ведуть історію версій вашого коду. Ваша база даних працює як окремий сервіс, тож відкат назад не поверне ваші дані.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":1180,"title":1181,"description":1182,"published":1183,"category":719,"image":1184,"draft":621},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Три способи зробити резервну копію бази Supabase, і чого бракує","Панель, pg_dump і керований сервіс. Що насправді зберігає кожен спосіб, що тихо лишає осторонь і який із них переживе втрату акаунта.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":1186,"title":1187,"description":1188,"published":1183,"category":617,"image":1189,"draft":621},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Які API-ключі безпечні у браузері, а які ні","Ваш ключ anon у Supabase створений, щоб бути публічним. Ключ service_role для цього не створений, і він ігнорує всі правила, які ви задали. Як їх розрізнити.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1794213654227]