[{"data":1,"prerenderedAt":1236},["ShallowReactive",2],{"blog-uk-supabase-schema-cache-column-error":3,"blog-index-uk":708},{"id":4,"title":5,"body":6,"category":666,"cover":667,"coverAlt":668,"description":669,"draft":670,"extension":671,"faq":672,"image":687,"keywords":688,"meta":697,"navigation":698,"ogTitle":5,"path":699,"published":700,"seo":701,"stem":702,"tldr":703,"updated":700,"__hash__":707},"blog_uk\u002Fblog\u002Fsupabase-schema-cache-column-error.md","Supabase PGRST204: \"Could not find the column in the schema cache\"",{"type":7,"value":8,"toc":652},"minimark",[9,13,24,31,39,44,47,50,73,115,118,124,128,140,149,158,226,238,241,249,256,265,274,278,281,284,290,313,316,340,360,365,369,377,386,402,406,427,440,445,449,452,458,472,475,481,484,488,491,499,502,514,518,521,529,535,549,553,556,563,583,592,610,614,645],[10,11,12],"p",{},"Ви попросили свій білдер додати номер телефону у форму профілю. Стовпець видно в\nTable Editor. Ви натискаєте «Зберегти», нічого не відбувається, а консоль\nбраузера показує ось це:",[14,15,20],"pre",{"className":16,"code":18,"language":19},[17],"language-text","{\n  \"code\": \"PGRST204\",\n  \"details\": null,\n  \"hint\": null,\n  \"message\": \"Could not find the 'phoneNumber' column of 'profiles' in the schema cache\"\n}\n","text",[21,22,18],"code",{"__ignoreMap":23},"",[10,25,26,27,30],{},"Supabase \"Could not find the column in the schema cache\" означає, що ваш\nзастосунок спробував зберегти поле, якого таблиця, такою, якою її бачить\nPostgREST, не має. PostgREST це частина Supabase, яка перетворює виклики\n",[21,28,29],{},"supabase.from(...)"," вашого застосунку на запити до бази даних. Він веде власний\nсписок кожної таблиці й кожного стовпця, який називається schema cache, щоб не\nпитати базу про її будову під час кожного запиту.",[10,32,33,34,38],{},"Ось що більшість відповідей подає неправильно: ",[35,36,37],"strong",{},"вони радять перезавантажити\nschema cache."," У Supabase кеш перезавантажується сам щоразу, коли змінюється\nтаблиця. Тож якщо ви щойно додали стовпець і все одно бачите цю помилку, кеш\nбуде найменш імовірною причиною. Зазвичай причина в назві.",[40,41,43],"h2",{"id":42},"що-означає-could-not-find-the-column-in-the-schema-cache","Що означає \"Could not find the column in the schema cache\"?",[10,45,46],{},"Один ключ у записі, який надіслав ваш застосунок, не має відповідного стовпця в\nцій таблиці.",[10,48,49],{},"Уявіть schema cache як дошку-покажчик у вестибюлі будівлі: рядок для кожного\nофісу, тобто таблиці, а під ним кожна кімната, тобто стовпець. Кожен запит\nвашого застосунку схожий на накладну. PostgREST звіряє кожен рядок накладної з\nдошкою, і кімнату, якої на дошці немає, розвертають ще на рецепції, перш ніж\nщось дістанеться ваших даних.",[10,51,52,53,56,57,60,61,64,65,72],{},"Повідомлення називає обидві сторони цього порівняння. У ",[21,54,55],{},"Could not find the 'phoneNumber' column of 'profiles' in the schema cache"," ",[21,58,59],{},"phoneNumber"," означає те,\nщо надіслав ваш застосунок, а ",[21,62,63],{},"profiles"," означає таблицю, куди це пішло. Ще три\nречі закладені у\n",[66,67,71],"a",{"href":68,"rel":69},"https:\u002F\u002Fgithub.com\u002FPostgREST\u002Fpostgrest\u002Fblob\u002Fmain\u002Fsrc\u002Flibrary\u002FPostgREST\u002FError.hs",[70],"nofollow","власному коді PostgREST",":",[74,75,76,84,99],"ul",{},[77,78,79,80,83],"li",{},"код ",[21,81,82],{},"PGRST204",", статус HTTP 400, тобто неправильним був сам запит",[77,85,86,87,90,91,94,95,98],{},"він з'являється лише під час запису: ",[21,88,89],{},".insert()",", ",[21,92,93],{},".update()"," і ",[21,96,97],{},".upsert()",".\nЧитання, в якому названо відсутній стовпець, падає з іншою помилкою, яку пише\nсам Postgres",[77,100,101,102,106,107,110,111,114],{},"він не дає жодної підказки. Для\n",[66,103,105],{"href":104},"\u002Fblog\u002Fsupabase-relation-does-not-exist","відсутньої таблиці"," PostgREST\nпропонує найближчу назву, яку знає; для відсутнього стовпця ",[21,108,109],{},"hint"," дорівнює ",[21,112,113],{},"null",", і\nпорівнювати доведеться вам",[10,116,117],{},"Кожен ключ в об'єкті, який ви передаєте в один із цих трьох викликів, має бути\nстовпцем цієї таблиці, написаним так, як його пише таблиця.",[119,120],"diagram",{"alt":121,"caption":122,"src":123},"Накладна з трьома рядками поруч із дошкою profiles, на якій чотири кімнати. Два рядки накладної ведуть до кімнат з такими самими назвами й позначені галочками. Третій, phoneNumber, закінчується бурштиновим знаком нерівності поруч із phone_number.","PostgREST порівнює кожен ключ, який надсилає ваш застосунок, зі стовпцями у своєму списку, літера в літеру. phoneNumber і phone_number це дві різні назви.","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fletter-for-letter-1600x700.png",[40,125,127],{"id":126},"причина-1-назва-не-збігається-літера-в-літеру","Причина 1: назва не збігається літера в літеру",[10,129,130,131,90,133,94,136,139],{},"Перевірка точна. Для PostgREST ",[21,132,59],{},[21,134,135],{},"phone_number",[21,137,138],{},"phonenumber","\nтри різні стовпці, і у вашій таблиці є щонайбільше один із них.",[10,141,142,143,145,146,148],{},"Сюди зазвичай потрапляють двома шляхами. Перший: зустрічаються дві звички\nназивати. JavaScript зазвичай пише поле як ",[21,144,59],{},", а стовпець Postgres\nзазвичай називається ",[21,147,135],{},". Код, який написав ваш білдер, і SQL, який\nвін виконав, можуть бути правильними кожен окремо і все одно не збігатися.",[10,150,151,152,157],{},"Другий: пастка з лапками. У SQL назва, набрана без подвійних лапок, переводиться\nв нижній регістр.\n",[66,153,156],{"href":154,"rel":155},"https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002Fcurrent\u002Fsql-syntax-lexical.html",[70],"Документація Postgres","\nкаже про це прямо: \"Quoting an identifier also makes it case-sensitive, whereas\nunquoted names are always folded to lower case.\"",[159,160,161,177],"table",{},[162,163,164],"thead",{},[165,166,167,171,174],"tr",{},[168,169,170],"th",{},"Що ви виконали в SQL Editor",[168,172,173],{},"Який стовпець з'явився",[168,175,176],{},"Що має надсилати застосунок",[178,179,180,196,211],"tbody",{},[165,181,182,188,192],{},[183,184,185],"td",{},[21,186,187],{},"alter table profiles add column phone_number text;",[183,189,190],{},[21,191,135],{},[183,193,194],{},[21,195,135],{},[165,197,198,203,207],{},[183,199,200],{},[21,201,202],{},"alter table profiles add column phoneNumber text;",[183,204,205],{},[21,206,138],{},[183,208,209],{},[21,210,138],{},[165,212,213,218,222],{},[183,214,215],{},[21,216,217],{},"alter table profiles add column \"phoneNumber\" text;",[183,219,220],{},[21,221,59],{},[183,223,224],{},[21,225,59],{},[10,227,228,229,231,232,234,235,237],{},"Саме середній рядок вводить в оману. SQL виглядає так, ніби створив\n",[21,230,59],{},", код надсилає ",[21,233,59],{},", а стовпець називається ",[21,236,138],{},".",[10,239,240],{},"Щоб побачити справжні назви, відкрийте таблицю в Table Editor і прочитайте\nзаголовки стовпців або виконайте це в SQL Editor:",[14,242,247],{"className":243,"code":245,"language":246,"meta":23},[244],"language-sql","select column_name\nfrom information_schema.columns\nwhere table_schema = 'public' and table_name = 'profiles';\n","sql",[21,248,245],{"__ignoreMap":23},[10,250,251,252,255],{},"Потім подивіться, що надіслав ваш застосунок. В інструментах розробника\nбраузера відкрийте вкладку «Мережа» (Network), клацніть невдалий запит до\n",[21,253,254],{},"\u002Frest\u002Fv1\u002Fprofiles"," і прочитайте його payload.",[10,257,258,259,261,262,264],{},"Безпечніше виправлення полягає в тому, щоб змінити застосунок, бо це нічого не\nчіпає у ваших даних. Попросіть білдер використовувати точну назву стовпця всюди,\nде це поле зберігається: \"стовпець у ",[21,260,63],{}," називається ",[21,263,135],{},";\nвикористовуй цю назву в кожному insert і update\". Перейменувати стовпець\nнатомість означає змінити таблицю, якою вже користуються, і будь-який інший\nекран, що досі використовує стару назву, зламається під час першого ж запуску.",[10,266,267,268,273],{},"Якщо ви будуєте з Lovable, прогорніть чат і пошукайте зміну бази даних, яку вас\nпросили схвалити.\n",[66,269,272],{"href":270,"rel":271},"https:\u002F\u002Fdocs.lovable.dev\u002Fintegrations\u002Fsupabase",[70],"Документація Lovable про Supabase","\nкаже, що він \"writes the SQL, shows it to you, and asks for your approval in the\nproject chat before running it\". Поки ви її не схвалите, стовпця не існує, хоч\nби чого чекав код.",[40,275,277],{"id":276},"причина-2-ключ-який-ніколи-не-був-стовпцем","Причина 2: ключ, який ніколи не був стовпцем",[10,279,280],{},"Запит несе щось, що таблиця ніколи не мала зберігати: пов'язані рядки, вкладені\nв insert, або поле, яке форма тримає для себе.",[10,282,283],{},"Саме від вкладеного insert люди чекають, що він спрацює:",[14,285,288],{"className":286,"code":287,"language":19},[17],"await supabase.from('orders').insert({\n  customer_id: user.id,\n  total: 42,\n  order_items: [{ product_id: 7, quantity: 2 }],\n})\n",[21,289,287],{"__ignoreMap":23},[10,291,292,293,296,297,300,301,306,307,312],{},"Він падає з ",[21,294,295],{},"Could not find the 'order_items' column of 'orders' in the schema cache",". Прочитати таку саму форму можна: ",[21,298,299],{},".select('*, order_items(*)')"," повертає\nзамовлення разом із його позиціями, тож здається, що і зворотний шлях мав би\nпрацювати. PostgREST читає кожен ключ запису як стовпець тієї однієї таблиці,\nкуди йде запит. Один користувач Supabase\n",[66,302,305],{"href":303,"rel":304},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fsupabase\u002Fissues\u002F50816",[70],"повідомив про це як про баг",",\nі відповідь, перш ніж issue закрили 18 жовтня 2026 року, була така: вкладених\ninsert просто немає серед можливостей. Запит на них відкритий у\n",[66,308,311],{"href":309,"rel":310},"https:\u002F\u002Fgithub.com\u002FPostgREST\u002Fpostgrest\u002Fissues\u002F818",[70],"трекері PostgREST"," з лютого\n2017 року.",[10,314,315],{},"Ще дві форми тієї самої проблеми:",[74,317,318,331],{},[77,319,320,321,323,324,327,328,330],{},"рядок, прочитаний разом із пов'язаними рядками, відредагований у формі й\nвідправлений назад цілим у ",[21,322,93],{},", тож доданий ",[21,325,326],{},"order_items"," чи\n",[21,329,63],{}," іде разом із ним",[77,332,333,334,336,337],{},"увесь стан форми, переданий просто в ",[21,335,89],{},", з полями, які потрібні формі,\nа не таблиці, наприклад ",[21,338,339],{},"confirmPassword",[10,341,342,343,346,347,350,351,354,355,359],{},"Виправлення: записуйте кожну таблицю окремо, спершу батьківську. Вставте\nзамовлення й попросіть повернути його id через ",[21,344,345],{},".select('id').single()",", потім\nвставте позиції з цим ",[21,348,349],{},"order_id",". Це два запити, тож якщо другий впаде,\nзамовлення залишиться збереженим без позицій. Коли такого не можна допустити,\nпокладіть обидва insert в одну функцію Postgres і викликайте її через ",[21,352,353],{},".rpc()",";\nвідповідь у тому issue називає це стандартним підходом. Тоді збережеться все або\nнічого. Якщо цей виклик натомість відповідає PGRST202,\n",[66,356,358],{"href":357},"\u002Fblog\u002Fsupabase-function-not-found","версія цієї помилки для функцій"," пояснює\nчому.",[119,361],{"alt":362,"caption":363,"src":364},"Верхня смуга: накладна з другою накладною всередині йде до дошки orders. Два її звичайні рядки позначені галочками, а вкладена зупиняється на бурштиновому хрестику, з'єднаному з табличкою PGRST204 і 400. Нижня смуга: дві накладні, надіслані одна за одною з номерами 1 і 2, кожна до своєї дошки, обидві з галочками.","Вкладену накладну читають як ще один стовпець першої таблиці. Надіслані окремо, спершу батьківська, обидві знаходять свою дошку.","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fa-key-that-is-not-a-column-1600x720.png",[40,366,368],{"id":367},"причина-3-зміна-пішла-в-інший-проєкт","Причина 3: зміна пішла в інший проєкт",[10,370,371,372,376],{},"Стовпець існує, але в базі даних, з якою ваш застосунок ніколи не говорить. Один\nакаунт Supabase може мати кілька проєктів, а\n",[66,373,375],{"href":374},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","гілка є окремим проєктом"," з власною\nбазою даних. Стовпець, доданий у SQL Editor не того проєкту, змінює дошку в\nіншій будівлі.",[10,378,379,380,385],{},"У\n",[66,381,384],{"href":382,"rel":383},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fsupabase\u002Fissues\u002F42183",[70],"issue #42183"," від Supabase,\nскарзі на те, що кеш \"does not update\", що б не пробували, один із розробників\nPostgREST відповів, що у скарзі названо два різні посилання на проєкт, і\nпопросив підтвердити, що зміну зроблено в тому проєкті, куди йшли запити.",[10,387,388,389,392,393,396,397,401],{},"Для перевірки потрібні дві адреси. Ваш застосунок звертається до\n",[21,390,391],{},"https:\u002F\u002F\u003Creference>.supabase.co",", і це видно на будь-якому запиті у вкладці\n«Мережа». Дашборд показує проєкт, у якому ви перебуваєте, за адресою\n",[21,394,395],{},"supabase.com\u002Fdashboard\u002Fproject\u002F\u003Creference>",". Обидва посилання мають бути одним і\nтим самим рядком.\n",[66,398,400],{"href":399},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Який проєкт мій"," пояснює, як його\nзнайти, якщо Supabase налаштовував хтось інший.",[40,403,405],{"id":404},"причина-4-кеш-справді-застарів","Причина 4: кеш справді застарів",[10,407,408,409,412,413,416,417,420,421,426],{},"У Supabase це рідкісний випадок, бо Supabase перезавантажує кеш за вас. Кожну\nбазу даних Supabase налаштовано з тригером подій ",[21,410,411],{},"pgrst_ddl_watch",", який\nспрацьовує після кожної зміни будови бази, ",[21,414,415],{},"ALTER TABLE"," теж, і надсилає\n",[21,418,419],{},"NOTIFY pgrst, 'reload schema'",": повідомлення, яке каже PostgREST перебудувати\nсвій список. Його можна прочитати в\n",[66,422,425],{"href":423,"rel":424},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fpostgres\u002Fblob\u002Fdevelop\u002Fmigrations\u002Fschema-17.sql",[70],"налаштуванні бази даних Supabase",".\nДодавання стовпця в Table Editor чи SQL Editor саме перемальовує дошку.",[10,428,429,430,435,436,439],{},"Усе йде не так, коли це повідомлення не доходить.\n",[66,431,434],{"href":432,"rel":433},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Ftroubleshooting\u002Fpostgrest-not-recognizing-new-columns-or-functions-bd75f5",[70],"Посібник Supabase з усунення несправностей","\nописує цей випадок: \"an underlying Postgres notification queue issue prevents\nPostgREST from receiving cache reload signals after schema changes\". Тоді журнал\nPostgREST показує ",[21,437,438],{},"Failed listening for database notifications on the \"pgrst\" channel",", і дошка лишається такою, як була, скільки б стовпців ви не додали.",[119,441],{"alt":442,"caption":443,"src":444},"Верхня смуга: ALTER TABLE додає стовпець до таблиці, дзвонить дзвіночок, лінія з написом NOTIFY pgrst доходить до дошки profiles, і на дошці з'являється така сама нова табличка. Нижня смуга: та сама зміна, лінію перерізає бурштиновий хрестик, а на дошці пунктирне порожнє місце там, де мала б бути нова табличка.","Кожен ALTER TABLE у Supabase сам надсилає повідомлення про перезавантаження. Застарілий кеш означає, що це повідомлення не дійшло.","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fthe-board-repaints-itself-1600x660.png",[40,446,448],{"id":447},"як-перезавантажити-schema-cache-у-supabase","Як перезавантажити schema cache у Supabase?",[10,450,451],{},"Виконайте один рядок у SQL Editor:",[14,453,456],{"className":454,"code":455,"language":246,"meta":23},[244],"NOTIFY pgrst, 'reload schema';\n",[21,457,455],{"__ignoreMap":23},[10,459,460,465,466,471],{},[66,461,464],{"href":462,"rel":463},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Ftroubleshooting\u002Frefresh-postgrest-schema",[70],"Сторінка Supabase про це","\nкаже, що під Results ви маєте побачити \"Success. No rows returned\". Для\nзастосунку, яким користуються, це безпечно.\n",[66,467,470],{"href":468,"rel":469},"https:\u002F\u002Fdocs.postgrest.org\u002Fen\u002Fv14\u002Freferences\u002Fschema_cache.html",[70],"Документація PostgREST","\nкаже \"Requests will wait until the schema cache reload is done\", тож ніхто з\nкористувачів застосунку не бачить помилки, поки це триває.",[10,473,474],{},"Якщо проблема в черзі сповіщень, повідомлення про перезавантаження застрягне так\nсамо, як автоматичне. Посібник з усунення несправностей дає для цього випадку\nдругий рядок:",[14,476,479],{"className":477,"code":478,"language":246,"meta":23},[244],"select pg_notification_queue_usage();\n",[21,480,478],{"__ignoreMap":23},[10,482,483],{},"За словами Supabase, він змушує PostgREST оновити кеш і \"does not require a\ndatabase instance or PostgREST service restart\". Потім спробуйте зберегти ще\nраз.",[40,485,487],{"id":486},"коли-перезавантаження-не-допомагає","Коли перезавантаження не допомагає",[10,489,490],{},"Перезапустіть проєкт, а якщо помилка переживе і це, поверніться до причин з 1 по\n3.",[10,492,493,494,498],{},"Перезапуск завжди дає PostgREST свіжий список. Той самий розробник PostgREST\nнаписав у #42183, що перезапущений PostgREST \"won't go live if it doesn't load a\nnew schema cache\". Restart project розташовано в Project Settings, далі General,\nа ",[66,495,497],{"href":496},"\u002Fblog\u002Fis-supabase-down-or-your-app","як перезапустити проєкт Supabase","\nпроводить через усе це, разом із кількома хвилинами, поки проєкт офлайн.",[10,500,501],{},"Отже, помилка, яка пережила перезапуск, походить зі свіжого й точного списку: у\nцій таблиці цього проєкту немає стовпця з такою назвою. Сам #42183, відкритий у\nсічні 2026 року людиною, яка вже пробувала перезавантаження, перезапуск і\nвидалення та повторне додавання стовпця, був ще відкритий, коли ми читали його\n21 жовтня 2026 року. Відповідь розробника там також радила оновитися до\nPostgREST 14 у налаштуваннях Infrastructure проєкту.",[10,503,504,505,508,509,513],{},"Викресліть зі свого списку видалення й повторне додавання.\n",[21,506,507],{},"alter table … drop column"," стирає кожне значення, збережене в цьому стовпці, а\nновий стовпець з тією самою назвою починається порожнім. Якщо ви збираєтеся\nзмінити таблицю, в яку пишуть справжні користувачі, збережіть копію бази даних\nдо зміни. ",[66,510,512],{"href":511},"\u002Fsupabase-backups","Reeve Care"," робить її за розкладом і зберігає\nзашифрованою, у власному сховищі Reeve в ЄС.",[40,515,517],{"id":516},"як-тримати-згенеровані-типи-в-актуальному-стані","Як тримати згенеровані типи в актуальному стані",[10,519,520],{},"Перегенеровуйте свої типи TypeScript після кожної зміни таблиці, і назва\nстовпця з помилкою може проявитися в редакторі раніше, ніж потрапить на живий\nсайт.",[10,522,523,524,72],{},"Supabase будує файл із ваших справжніх стовпців, через дашборд або однією\nкомандою з його\n",[66,525,528],{"href":526,"rel":527},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fapi\u002Frest\u002Fgenerating-types",[70],"посібника з генерації типів",[14,530,533],{"className":531,"code":532,"language":19},[17],"npx supabase gen types typescript --project-id \"$PROJECT_REF\" --schema public > database.types.ts\n",[21,534,532],{"__ignoreMap":23},[10,536,537,538,541,542,545,546,548],{},"Коли клієнт створено з цими типами, ",[21,539,540],{},"createClient\u003CDatabase>(…)",", тип ",[21,543,544],{},"Insert","\nкожної таблиці перелічує стовпці, які приймає ",[21,547,89],{},". Стовпець із помилкою\nв назві в об'єкті, написаному повністю прямо у виклику, тоді позначається як\nпомилка ще до публікації. Документація Lovable каже, що він \"regenerates the\nTypeScript types your app uses\" після зміни бази даних. Файл типів,\nзгенерований до вашої останньої зміни таблиці, і далі перелічує старі стовпці.",[40,550,552],{"id":551},"як-змінити-таблицю-якою-користуються-і-не-втратити-те-що-в-ній-є","Як змінити таблицю, якою користуються, і не втратити те, що в ній є",[10,554,555],{},"Збережіть копію до зміни і одразу знайте, чи застосунок після неї ще відповідає.",[10,557,558],{},[35,559,560,562],{},[66,561,512],{"href":511}," зберігає копію вашої бази даних Supabase:",[74,564,565,568,571,574,577,580],{},[77,566,567],{},"зашифровану копію за розкладом, у власному сховищі Reeve в ЄС, поза вашим акаунтом Supabase",[77,569,570],{},"остання копія перед вашою зміною містить таблиці й стовпці такими, якими вони були, разом із рядками",[77,572,573],{},"кожну копію перевірено, перш ніж вона зарахується, підрахунком рядків у кожній таблиці",[77,575,576],{},"також ваші завантажені файли, щойно ви підключите обліковий доступ до Storage",[77,578,579],{},"відновлення в один клік, перед яким робиться страхова копія поточного стану",[77,581,582],{},"усе, що робить Monitor",[10,584,585],{},[35,586,587,591],{},[66,588,590],{"href":589},"\u002Fwebsite-monitoring","Reeve Monitor"," і далі перевіряє ззовні:",[74,593,594,597,600,607],{},[77,595,596],{},"чи ваш застосунок доступний, перевірка щохвилини, тож зламану кнопку «Зберегти» легко відрізнити від збою",[77,598,599],{},"повну перевірку безпеки щогодини, до трьох застосунків",[77,601,602,603,606],{},"повідомлення, коли результат ",[35,604,605],{},"змінюється",", тож деплой, який змінює те, що відкриває ваш застосунок, дійде до вас без того, щоб ви ходили дивитися",[77,608,609],{},"щомісячний звіт простою мовою про те, що він бачив",[40,611,613],{"id":612},"що-зробити-зараз","Що зробити зараз",[615,616,617],"key-takeaways",{},[74,618,619,622,625,628,631,642],{},[77,620,621],{},"Прочитайте дві назви в повідомленні: ключ, який надіслав ваш застосунок, і таблицю, куди він пішов.",[77,623,624],{},"Порівняйте цей ключ зі стовпцем у Table Editor, літера в літеру. Назва, набрана в SQL без лапок, зберігається в нижньому регістрі.",[77,626,627],{},"Пошукайте ключі, які не є стовпцями: пов'язані рядки, вкладені в insert, або цілий рядок, відправлений назад разом із пов'язаними рядками. Записуйте кожну таблицю окремо або покладіть обидва записи в одну функцію.",[77,629,630],{},"Перевірте, що посилання в адресі Supabase вашого застосунку збігається з проєктом, який ви змінили.",[77,632,633,634,637,638,641],{},"Якщо все це збігається, виконайте ",[21,635,636],{},"NOTIFY pgrst, 'reload schema';",", потім ",[21,639,640],{},"select pg_notification_queue_usage();",", і перезапускайте проєкт, лише якщо жодне з них не допомогло.",[77,643,644],{},"Перегенеровуйте свої типи TypeScript після кожної зміни таблиці.",[10,646,647,648,651],{},"Почніть із назви стовпця, яку цитує повідомлення, бо вона точно відповідає тому,\nщо надіслав ваш застосунок, а Table Editor точно показує, що є в таблиці. Перш\nніж перейменовувати чи видаляти щось у таблиці, якою користуються люди,\n",[66,649,650],{"href":511},"збережіть копію бази даних"," до зміни.",{"title":23,"searchDepth":653,"depth":653,"links":654},3,[655,657,658,659,660,661,662,663,664,665],{"id":42,"depth":656,"text":43},2,{"id":126,"depth":656,"text":127},{"id":276,"depth":656,"text":277},{"id":367,"depth":656,"text":368},{"id":404,"depth":656,"text":405},{"id":447,"depth":656,"text":448},{"id":486,"depth":656,"text":487},{"id":516,"depth":656,"text":517},{"id":551,"depth":656,"text":552},{"id":612,"depth":656,"text":613},"Основи безпеки","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcover-1200x630.png","Дошка-покажчик у вестибюлі з порожнім місцем у списку кімнат, а перед нею накладна, в якій один рядок підсвічено бурштиновим.","Supabase \"Could not find the column in the schema cache\" зазвичай означає, що назва не збігається. Чотири перевірки і рядок для перезавантаження.",false,"md",[673,676,679,681,684],{"q":674,"a":675},"Що означає PGRST204?","PGRST204 це код, який PostgREST, частина Supabase, що відповідає на звернення вашого застосунку до бази даних, дає запису, в якому названо стовпець, якого таблиця не має. Він повертається з HTTP 400 і повідомленням \"Could not find the 'x' column of 'y' in the schema cache\", де x означає ключ, який надіслав ваш застосунок, а y означає таблицю, куди його надіслано. Його видають insert, update та upsert.",{"q":677,"a":678},"Я додав стовпець, а воно все одно не працює. Чому?","Зазвичай через назву. Перевірте, що ваш застосунок надсилає точно ту назву, яка збережена (стовпець, доданий у SQL як phoneNumber без лапок, зберігається як phonenumber), що ви додали його в тому проєкті, до якого звертається застосунок, і що більше нічого в запиті не є ключем, якого таблиця не має. Supabase сам перезавантажує schema cache після кожного ALTER TABLE, тож застарілий кеш варто підозрювати останнім.",{"q":448,"a":680},"Виконайте NOTIFY pgrst, 'reload schema'; у SQL Editor. Якщо нічого не змінилося, посібник Supabase з усунення несправностей дає другу команду, select pg_notification_queue_usage();, для випадку, коли повідомлення про перезавантаження застрягли. Запити, що надходять під час перезавантаження, чекають, поки воно закінчиться.",{"q":682,"a":683},"Чи очищує кеш пауза проєкту?","Так. PostgREST будує свіжий schema cache щоразу, коли запускається, а відновлення призупиненого проєкту запускає його знову. Restart project у Project Settings, далі General, робить те саме без паузи. Якщо помилка переживає будь-що з цього, кеш від початку був правий: у цій таблиці цього проєкту стовпця немає.",{"q":685,"a":686},"Чому вкладені insert падають з цією помилкою?","Бо PostgREST читає кожен ключ insert як стовпець однієї таблиці, а ключ, у якому лежать пов'язані рядки, виявляється стовпцем, якого він не знаходить. Читати пов'язані рядки одним запитом можна, а записувати їх так ніколи не було можливо. Спершу вставте батьківський рядок, потім дочірні з його id, або зробіть обидва записи в одній функції Postgres, яку викликаєте через rpc().","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",[689,690,691,692,693,694,695,696],"could not find the column in the schema cache","pgrst204","supabase could not find the column of in the schema cache","supabase schema cache не оновлюється","notify pgrst reload schema","supabase новий стовпець не працює","перезавантажити schema cache supabase","supabase вкладений insert",{},true,"\u002Fblog\u002Fsupabase-schema-cache-column-error","2026-10-21",{"title":5,"description":669},"blog\u002Fsupabase-schema-cache-column-error",[704,705,706],"Supabase \"Could not find the column in the schema cache\" (PGRST204) означає, що ваш застосунок спробував зберегти поле, якого таблиця не має у своєму списку. PostgREST звіряє кожен ключ insert або update зі своєю копією вашої схеми, літера в літеру.","Звичайна причина в назві: phoneNumber, надісланий у стовпець phone_number, або ключ, який ніколи не був стовпцем, наприклад пов'язані рядки, вкладені в insert.","Supabase сам перезавантажує цю копію щоразу, коли змінюється таблиця. Коли вона справді застаріла, NOTIFY pgrst, 'reload schema'; у SQL Editor перезавантажує її, поки застосунок працює далі.","32wuqhz-WsOfvnWHkfY9rGx_jUwKVy6Q0G1hGHOUmZU",[709,715,721,727,733,739,745,751,757,763,769,776,782,788,794,800,806,812,817,822,823,829,835,841,847,853,859,865,871,877,883,889,895,901,907,913,919,925,931,937,942,948,954,960,966,972,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,1150,1156,1162,1167,1173,1179,1185,1191,1197,1202,1208,1214,1220,1225,1231],{"path":710,"title":711,"description":712,"published":713,"category":666,"image":714,"draft":670},"\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":716,"title":717,"description":718,"published":719,"category":666,"image":720,"draft":670},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","Помилка 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":722,"title":723,"description":724,"published":725,"category":666,"image":726,"draft":670},"\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":728,"title":729,"description":730,"published":731,"category":666,"image":732,"draft":670},"\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":734,"title":735,"description":736,"published":737,"category":666,"image":738,"draft":670},"\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":740,"title":741,"description":742,"published":743,"category":666,"image":744,"draft":670},"\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":746,"title":747,"description":748,"published":749,"category":666,"image":750,"draft":670},"\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":752,"title":753,"description":754,"published":755,"category":666,"image":756,"draft":670},"\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","Чому Supabase перенаправляє посилання з листів на localhost:3000","Якщо Supabase перенаправляє на localhost:3000, Site URL так і не змінили або вашої адреси немає в Redirect URLs. Як виправити і якої маски уникати.","2026-11-02","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",{"path":758,"title":759,"description":760,"published":761,"category":666,"image":762,"draft":670},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","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":764,"title":765,"description":766,"published":767,"category":666,"image":768,"draft":670},"\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":770,"title":771,"description":772,"published":773,"category":774,"image":775,"draft":670},"\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":777,"title":778,"description":779,"published":780,"category":666,"image":781,"draft":670},"\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":783,"title":784,"description":785,"published":786,"category":666,"image":787,"draft":670},"\u002Fblog\u002Fsupabase-invalid-login","\"Invalid login credentials\" у Supabase: три причини","Supabase відповідає \"Invalid login credentials\" на неправильний пароль, невідому пошту й акаунт Google. Як зрозуміти, що саме.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":789,"title":790,"description":791,"published":792,"category":666,"image":793,"draft":670},"\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":795,"title":796,"description":797,"published":798,"category":666,"image":799,"draft":670},"\u002Fblog\u002Fcertificate-not-trusted","Сертифікат не довірений: три причини, крім закінчення строку","Сертифікат не довірений, хоча дата в порядку? Він називає іншу адресу, підписав сам себе або в його ланцюжку бракує ланки. Як зрозуміти, що саме.","2026-10-26","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",{"path":801,"title":802,"description":803,"published":804,"category":666,"image":805,"draft":670},"\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":807,"title":808,"description":809,"published":810,"category":666,"image":811,"draft":670},"\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":104,"title":813,"description":814,"published":815,"category":666,"image":816,"draft":670},"Supabase \"relation does not exist\", хоча таблиця на місці","Supabase \"relation does not exist\" або PGRST205: жодна таблиця не має такої назви в цій схемі. Чотири перевірки, і на що зважити, відкриваючи схему.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":357,"title":818,"description":819,"published":820,"category":666,"image":821,"draft":670},"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":699,"title":5,"description":669,"published":700,"category":666,"image":687,"draft":670},{"path":824,"title":825,"description":826,"published":827,"category":666,"image":828,"draft":670},"\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":830,"title":831,"description":832,"published":833,"category":666,"image":834,"draft":670},"\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":836,"title":837,"description":838,"published":839,"category":666,"image":840,"draft":670},"\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":842,"title":843,"description":844,"published":845,"category":666,"image":846,"draft":670},"\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":848,"title":849,"description":850,"published":851,"category":666,"image":852,"draft":670},"\u002Fblog\u002Fsupabase-invalid-jwt","Supabase invalid JWT: який ключ перестав працювати?","Помилка Supabase invalid JWT — це PGRST301: підписаний токен не пройшов перевірку. У новому проєкті йдеться про сесію, а не про ключ API.","2026-10-16","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",{"path":854,"title":855,"description":856,"published":857,"category":666,"image":858,"draft":670},"\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":860,"title":861,"description":862,"published":863,"category":666,"image":864,"draft":670},"\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":866,"title":867,"description":868,"published":869,"category":666,"image":870,"draft":670},"\u002Fblog\u002Fwhat-is-supabase","Що таке Supabase? База даних, яку обрав ваш білдер","Що таке Supabase: база даних, вхід і сховище файлів за вашим застосунком. Supabase тримає сервери, а правила про те, хто читає ваші рядки, ваші.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":872,"title":873,"description":874,"published":875,"category":666,"image":876,"draft":670},"\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":878,"title":879,"description":880,"published":881,"category":666,"image":882,"draft":670},"\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":884,"title":885,"description":886,"published":887,"category":666,"image":888,"draft":670},"\u002Fblog\u002Fbase44-security-scan","Сканування безпеки Base44: те, що бачить лише воно","Сканування безпеки Base44 перевіряє сім видів проблем зсередини. Ось половина, яку читає тільки воно, і половина, на яку воно ніколи не дивиться.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":890,"title":891,"description":892,"published":893,"category":666,"image":894,"draft":670},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Ваш API-ключ витік. Порядок дій","API-ключ витік, і ви не знаєте, що робити першим. Не кожен ключ у вашому фронтенді є витоком, а порядок важить більше за швидкість.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":896,"title":897,"description":898,"published":899,"category":666,"image":900,"draft":670},"\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":902,"title":903,"description":904,"published":905,"category":666,"image":906,"draft":670},"\u002Fblog\u002Fno-api-key-found-in-request","\"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":908,"title":909,"description":910,"published":911,"category":666,"image":912,"draft":670},"\u002Fblog\u002Fis-base44-safe","Чи безпечний Base44? Дані 5 442 застосунків","Чи безпечний Base44? Ми прогнали дев’ять перевірок на 5 442 робочих застосунках Base44. Майже всі отримали B з причин, яких власник ніколи не обирав.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":914,"title":915,"description":916,"published":917,"category":666,"image":918,"draft":670},"\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":920,"title":921,"description":922,"published":923,"category":666,"image":924,"draft":670},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Чи відкритий ваш файл .env? Дванадцять шляхів для перевірки","Чи відкритий ваш файл .env на вашому власному вебсервері? Дванадцять адрес скажуть це за хвилину, а влучання означає, що все в ньому вже публічне.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":926,"title":927,"description":928,"published":929,"category":666,"image":930,"draft":670},"\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":932,"title":933,"description":934,"published":935,"category":666,"image":936,"draft":670},"\u002Fblog\u002Fis-bolt-safe","Чи безпечний Bolt? Що показали 1 123 застосунки Bolt","Чи безпечний Bolt? Ми прогнали 1 123 живі застосунки Bolt через дев’ять перевірок. Хостинг був чистим. Знахідки: ключі й відкриті таблиці в самих застосунках.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":496,"title":938,"description":939,"published":940,"category":666,"image":941,"draft":670},"Supabase не працює чи проблема у вашому застосунку? Як розрізнити","Supabase не працює чи зламався ваш застосунок? Пауза, повна база й ваша власна помилка виглядають однаково. Чотири перевірки їх розрізняють.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":943,"title":944,"description":945,"published":946,"category":666,"image":947,"draft":670},"\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":949,"title":950,"description":951,"published":952,"category":666,"image":953,"draft":670},"\u002Fblog\u002Fsupabase-free-plan-limits","Ліміти безкоштовного тарифу Supabase і що стається на кожному","Ліміти безкоштовного тарифу Supabase: 500 МБ бази, 5 ГБ egress і жодних резервних копій. Що стається на кожній межі і що змінює Pro за $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":955,"title":956,"description":957,"published":958,"category":774,"image":959,"draft":670},"\u002Fblog\u002Ftest-your-supabase-backup","Перевірте резервну копію Supabase до того, як вона знадобиться","Як перевірити резервну копію Supabase: відновити в тестовий проєкт, порахувати рядки, увійти й знайти рядок, якого бракує обрізаному файлу.","2026-09-28","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":961,"title":962,"description":963,"published":964,"category":774,"image":965,"draft":670},"\u002Fblog\u002Fsupabase-backup-github-action","Безкоштовна резервна копія Supabase через GitHub Action і підступ","Резервна копія Supabase через GitHub Action безкоштовна й годиться багатьом застосункам. Робочий процес, потрібний рядок підключення та egress.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":967,"title":968,"description":969,"published":970,"category":774,"image":971,"draft":670},"\u002Fblog\u002Fdownload-your-supabase-backup","Чому ви не можете завантажити резервну копію Supabase","Завантажити резервну копію Supabase на сучасному проєкті не вийде: щоденна копія там фізична. Як це перевірити і як тримати власну копію.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":973,"title":974,"description":975,"published":970,"category":666,"image":976,"draft":670},"\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":978,"title":979,"description":980,"published":981,"category":666,"image":982,"draft":670},"\u002Fblog\u002Fopen-api-endpoint-exposed","Чи є відкритий API-ендпоінт проблемою безпеки? Читайте JSON","Ваше сканування позначило відкритий API-ендпоінт. Чи це важливо, залежить від того, що повернулося, і більшість знайдених належали платформі.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":984,"title":985,"description":986,"published":987,"category":666,"image":988,"draft":670},"\u002Fblog\u002Flovable-security-scan","Сканування безпеки Lovable: чого воно не доведе","Сканування безпеки Lovable: що перевіряють Quick scan і Deep scan, коли запускається кожне, і єдине, чого не доведе жодне сканування зсередини.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":990,"title":991,"description":992,"published":993,"category":774,"image":994,"draft":670},"\u002Fblog\u002Fsupabase-backup-auth-users","Чому у вашому дампі Supabase немає користувачів","Запустіть supabase db dump окремо і отримаєте форму вашої бази та жодного її рядка, без схеми auth, у якій живуть ваші користувачі.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":996,"title":997,"description":998,"published":999,"category":666,"image":1000,"draft":670},"\u002Fblog\u002Fdomain-and-certificate-expiry","Домен закінчився, сайт лежить: що буде далі","Ваш домен закінчився і сайт лежить. Ось який годинник уже пішов, чому прострочений сертифікат це менша з двох бід, і як перевірити обидва.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":1002,"title":1003,"description":1004,"published":1005,"category":666,"image":1006,"draft":670},"\u002Fblog\u002Fis-lovable-safe","Чи безпечний Lovable? Що показали 18 554 застосунки Lovable","Чи безпечний Lovable? Ми прогнали 18 554 живі застосунки Lovable через дев’ять перевірок. Платформа виявилася найчистішою з п’яти. Знахідки були в застосунках.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":1008,"title":1009,"description":1010,"published":1011,"category":666,"image":1012,"draft":670},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Чек-лист безпеки для vibe coding, у девʼяти перевірках","Чек-лист безпеки для vibe coding із девʼяти пунктів, кожен з яких будь-хто може перевірити у вашому живому застосунку ззовні, і кожен має тест на один рядок.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":1014,"title":1015,"description":1016,"published":1017,"category":666,"image":1018,"draft":670},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Секретний ключ Stripe у фронтенді може рухати гроші","Секретний ключ Stripe, відкритий у вашому фронтенді, може повертати кошти, списувати й читати кожну картку клієнта. А ключ pk_live_ там і має бути.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":1020,"title":1021,"description":1022,"published":1023,"category":666,"image":1024,"draft":670},"\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":1026,"title":1027,"description":1028,"published":1029,"category":666,"image":1030,"draft":670},"\u002Fblog\u002Fbase44-source-maps","Безпека Base44: що позначає скан і що з цього виправляти вам","Безпека Base44 на 5 438 просканованих застосунках: три знахідки майже на кожному належать платформі, source map є бейджем Base44, а ваша частина коротка.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":1032,"title":1033,"description":1034,"published":1035,"category":666,"image":1036,"draft":670},"\u002Fblog\u002Fis-cursor-ai-safe","Чи безпечний Cursor AI? Редактор, код і опублікований застосунок","Чи безпечний Cursor AI? Три запитання в одному пошуку: що Cursor зберігає, у чому помиляється його код і чи відкритий застосунок, який ви опублікували.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":1038,"title":1039,"description":1040,"published":1041,"category":666,"image":1042,"draft":670},"\u002Fblog\u002Fis-replit-safe","Чи безпечний Replit? Що ми знайшли в 3 042 живих застосунках Replit","Чи безпечний Replit? Ми прогнали 3 042 живі застосунки Replit через дев’ять зовнішніх перевірок. Знахідки були в опублікованому застосунку, а не в хостингу.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":1044,"title":1045,"description":1046,"published":1047,"category":774,"image":1048,"draft":670},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: у копії бази даних немає жодного файлу","Supabase storage backup це окрема робота. Копії бази даних зберігають список ваших файлів і жодного з них, тож після відновлення кожне завантаження зламане.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":1050,"title":1051,"description":1052,"published":1053,"category":774,"image":1054,"draft":670},"\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":1056,"title":1057,"description":1058,"published":1059,"category":774,"image":1060,"draft":670},"\u002Fblog\u002Fsupabase-project-paused-recover","Проєкт Supabase на паузі? Ваші дані нікуди не зникли","Supabase поставив ваш проєкт на паузу після тижня без активності. Нічого не видалено, кнопка Restore стоїть поруч із назвою, і у вас є рік, щоб натиснути.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":1062,"title":1063,"description":1064,"published":1065,"category":666,"image":1066,"draft":670},"\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":1068,"title":1069,"description":1070,"published":1071,"category":666,"image":1072,"draft":670},"\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":1074,"title":1075,"description":1076,"published":1077,"category":666,"image":1078,"draft":670},"\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":1080,"title":1081,"description":1082,"published":1083,"category":666,"image":1084,"draft":670},"\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":1086,"title":1087,"description":1088,"published":1089,"category":666,"image":1090,"draft":670},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Сканери безпеки для vibe coding у порівнянні, наш теж","Найкращий сканер безпеки для vibe coding залежить від трьох питань, на які не відповідає жоден перелік функцій. Вісім інструментів і ціни.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":1092,"title":1093,"description":1094,"published":1095,"category":666,"image":1096,"draft":670},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: п’ять перевірок, які зробите самі","Supabase security checker читає ваш опублікований застосунок, а не налаштування проєкту. Ось п’ять перевірок і як виконати кожну самостійно.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":1098,"title":1099,"description":1100,"published":1101,"category":666,"image":1102,"draft":670},"\u002Fblog\u002Fvibe-coding-security-scanner","Сканер безпеки для vibe coding: чого не бачить скан URL","Сканер безпеки для vibe coding читає ваш робочий застосунок ззовні. Що це охоплює, чотири речі, яких він не бачить, і як читати результат.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":1104,"title":1105,"description":1106,"published":1107,"category":666,"image":1108,"draft":670},"\u002Fblog\u002Fmissing-security-headers","Відсутні заголовки безпеки: коли це справді важливо","Відсутні заголовки безпеки трапляються в наших звітах найчастіше. Від чого вони захищають і коли це найменш терміновий рядок вашого звіту.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":1110,"title":1111,"description":1112,"published":1113,"category":666,"image":1114,"draft":670},"\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":1116,"title":1117,"description":1118,"published":1119,"category":666,"image":1120,"draft":670},"\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":1122,"title":1123,"description":1124,"published":1125,"category":774,"image":1126,"draft":670},"\u002Fblog\u002Fsupabase-backup-tools-compared","Інструменти резервного копіювання Supabase, і наш серед них","Чотири види інструментів резервного копіювання Supabase, що копіює кожен і коли безкоштовна GitHub Action виграє в будь-якої оплати, нашої теж.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":1128,"title":1129,"description":1130,"published":1131,"category":666,"image":1132,"draft":670},"\u002Fblog\u002Freplit-secrets-explained","Як користуватися секретами в Replit і що все одно публікується","Як користуватися секретами в Replit: додати, прочитати і усунути дві причини undefined. А ще ключі, які цей інструмент не здатен зберегти в таємниці.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":1134,"title":1135,"description":1136,"published":1137,"category":774,"image":1138,"draft":670},"\u002Fblog\u002Fback-up-supabase-free-tier","Резервні копії на безкоштовному тарифі Supabase без терміналу","На безкоштовному тарифі Supabase резервних копій немає: копію робите ви. Як зробити її з панелі та що втрачає шлях через CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":1140,"title":1141,"description":1142,"published":1143,"category":666,"image":1144,"draft":670},"\u002Fblog\u002Fis-supabase-secure","Чи безпечний Supabase? Так. Ваш проєкт це інше питання","Чи безпечний Supabase? Платформа проходить аудити, шифрує дані й тримає пентести. Їхня документація каже, де це закінчується і починаються ваші налаштування.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":399,"title":1146,"description":1147,"published":1148,"category":666,"image":1149,"draft":670},"Де знайти API-ключі Supabase: anon, service_role і URL","URL проєкту, ключ anon і ключ service_role лежать на одній сторінці панелі. Ось де вона, і яке з чотирьох значень має бути у вашому застосунку.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":1151,"title":1152,"description":1153,"published":1154,"category":666,"image":1155,"draft":670},"\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":1157,"title":1158,"description":1159,"published":1160,"category":666,"image":1161,"draft":670},"\u002Fblog\u002Fcors-wildcard-security-risk","Чи є вайлдкард CORS ризиком для безпеки? Майже ніколи.","Чи є вайлдкард CORS ризиком для безпеки? Зазвичай це типове налаштування вашого білдера, і воно не видає нічого, що ваш сервер і так віддавав кожному.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":374,"title":1163,"description":1164,"published":1165,"category":774,"image":1166,"draft":670},"Branching у Supabase це не бекап. Він іде тільки вперед.","Чому branching у Supabase це не бекап: гілка стартує без ваших даних, а мердж переносить саму лише схему. Для чого він потрібен і що брати замість нього.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":1168,"title":1169,"description":1170,"published":1171,"category":774,"image":1172,"draft":670},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Як відновити резервну копію Supabase, і що ламається потім","Як відновити резервну копію Supabase з панелі або з файлу дампа, що саме замінює відновлення і чому ваш застосунок може лишитися зламаним після нього.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":1174,"title":1175,"description":1176,"published":1177,"category":666,"image":1178,"draft":670},"\u002Fblog\u002Fsupabase-storage-bucket-public","Ваш бакет Supabase Storage публічний. Чи це проблема?","Публічний бакет Supabase Storage означає, що той, хто має URL файлу, може його відкрити. Він не означає, що хтось може переглянути список вмісту.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":1180,"title":1181,"description":1182,"published":1183,"category":666,"image":1184,"draft":670},"\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":1186,"title":1187,"description":1188,"published":1189,"category":774,"image":1190,"draft":670},"\u002Fblog\u002Fai-agent-deleted-my-database","ШІ-агент видалив мої дані в Supabase. Що можна відновити?","ШІ-агент видалив дані з вашої бази. Те, що ви зможете відновити, вирішилося раніше, а наступні хвилини вирішують, скільки з цього вціліє.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":1192,"title":1193,"description":1194,"published":1195,"category":666,"image":1196,"draft":670},"\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":1198,"title":1199,"description":1200,"published":1195,"category":666,"image":1201,"draft":670},"\u002Fblog\u002Fsource-maps-exposed-in-production","Відкриті source maps: ваш застосунок публікує свій вихідний код","Відкрита source map дає будь-кому прочитати оригінальний код вашого застосунку, разом із коментарями. Перевірка за 30 секунд, і що важить насправді.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":1203,"title":1204,"description":1205,"published":1206,"category":666,"image":1207,"draft":670},"\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":1209,"title":1210,"description":1211,"published":1212,"category":774,"image":1213,"draft":670},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Чи робить Supabase резервні копії моєї бази? Залежить від тарифу.","Чи робить Supabase резервні копії вашої бази даних? На платних тарифах щодня, на безкоштовному жодної. Як дізнатися, що у вас насправді є.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":1215,"title":1216,"description":1217,"published":1218,"category":666,"image":1219,"draft":670},"\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":1221,"title":1222,"description":1223,"published":1218,"category":774,"image":1224,"draft":670},"\u002Fblog\u002Fversion-history-is-not-a-backup","Історія версій не є резервною копією. Вона не поверне таблицю.","Lovable і Bolt ведуть історію версій вашого коду. Ваша база даних працює як окремий сервіс, тож відкат назад не поверне ваші дані.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":1226,"title":1227,"description":1228,"published":1229,"category":774,"image":1230,"draft":670},"\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":1232,"title":1233,"description":1234,"published":1229,"category":666,"image":1235,"draft":670},"\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",1794213654352]