[{"data":1,"prerenderedAt":1193},["ShallowReactive",2],{"blog-pt-supabase-auth-redirects-to-localhost":3,"blog-index-pt":663},{"id":4,"title":5,"body":6,"category":620,"cover":621,"coverAlt":622,"description":623,"draft":624,"extension":625,"faq":626,"image":642,"keywords":643,"meta":651,"navigation":652,"ogTitle":653,"path":654,"published":655,"seo":656,"stem":657,"tldr":658,"updated":655,"__hash__":662},"blog_pt\u002Fblog\u002Fsupabase-auth-redirects-to-localhost.md","Por que o Supabase redireciona links de e-mail para localhost:3000",{"type":7,"value":8,"toc":608},"minimark",[9,13,24,31,38,46,51,54,73,79,95,99,102,132,154,166,172,180,184,187,218,222,225,238,241,245,256,281,299,320,340,409,415,419,422,429,442,445,448,484,489,492,499,503,506,515,529,538,558,562,596],[10,11,12],"p",{},"Um usuário novo se cadastra no seu app no ar, abre o e-mail de confirmação e\naperta o botão. O navegador dele abre uma página que diz \"This site can't be\nreached\" e \"localhost refused to connect\" (assim num Chrome em inglês), acima\nde um endereço que começa assim:",[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],{},"Se o seu app usa o fluxo PKCE, ele termina em ",[21,28,29],{},"?code=…",". Você construiu o app\nno Lovable, Bolt, v0, Cursor, Claude Code ou Replit, na pré-visualização ele\nfuncionava perfeitamente, e o login com senha continua funcionando.",[10,32,33,34,37],{},"Um redirecionamento do Supabase para localhost significa que o Supabase Auth, a\nparte do Supabase que faz o login das pessoas, terminou o trabalho dele e\ndepois mandou a pessoa para a Site URL do seu projeto, que ainda diz\n",[21,35,36],{},"http:\u002F\u002Flocalhost:3000",". Esse endereço quer dizer \"este computador\". No\ncomputador do seu usuário não tem nada ali. A solução são duas configurações\nnuma página do painel do Supabase.",[10,39,40,41,45],{},"Esta é a parte que as soluções rápidas da internet erram: ",[42,43,44],"strong",{},"o curinga que faz\nessa mensagem sumir com uma linha é também o que deixa o link de um estranho\nmandar os seus usuários para a página dele, já com login feito."," As\nconfigurações abaixo fazem os links funcionarem e mantêm essa porta fechada.",[47,48,50],"h2",{"id":49},"o-que-significa-um-redirecionamento-do-supabase-para-localhost","O que significa um redirecionamento do Supabase para localhost?",[10,52,53],{},"Significa que o Supabase mandou a pessoa para o endereço padrão do seu projeto,\nporque não aceitou um melhor.",[10,55,56,57,64,65,68,69,72],{},"Todo e-mail que o Supabase envia por você, seja uma confirmação de cadastro, um\nmagic link, uma redefinição de senha ou um convite, leva primeiro ao endereço\ndo seu próprio projeto. O\n",[58,59,63],"a",{"href":60,"rel":61},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fauth\u002Fauth-email-templates",[62],"nofollow","guia de modelos de e-mail","\ndo Supabase mostra o formato:\n",[21,66,67],{},"https:\u002F\u002Fproject-ref.supabase.co\u002Fauth\u002Fv1\u002Fverify?token=…&type=email&redirect_to=https:\u002F\u002Fexample.com\u002Fpath",".\nAli o Supabase verifica o token e depois manda o navegador para o que\n",[21,70,71],{},"redirect_to"," indicar.",[10,74,75,76,78],{},"Pense nisso como uma placa de sinalização na porta do Supabase. Cada pessoa que\nabre um link faz login na porta e depois segue, com a chave na mão, por uma das\nsetas. Quem coloca as setas é você. A Site URL é a seta que todo mundo pega\nquando nenhuma outra serve, e num projeto novo ela aponta para\n",[21,77,36],{},": a oficina onde o app foi construído, que na máquina de\nqualquer outra pessoa é uma sala vazia.",[10,80,81,82,87,88,91,92,94],{},"O\n",[58,83,86],{"href":84,"rel":85},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fauth\u002Fredirect-urls",[62],"guia de redirecionamentos","\ndo Supabase diz que a Site URL define o redirecionamento padrão quando o código\nnão indica nenhum ",[21,89,90],{},"redirectTo",", pede que você a troque de\n",[21,93,36],{}," para o seu endereço de produção e chama essa\nconfiguração de crítica para confirmações por e-mail e redefinições de senha.",[47,96,98],{"id":97},"por-que-o-supabase-ignora-o-endereço-que-o-meu-app-pediu","Por que o Supabase ignora o endereço que o meu app pediu?",[10,100,101],{},"Porque esse endereço não está na sua lista Redirect URLs, e o Supabase recorre\na outro sem avisar você.",[10,103,104,105,108,109,112,113,116,117,108,119,112,122,125,126,131],{},"O seu app pode dizer onde as pessoas devem chegar. Na biblioteca JavaScript do\nSupabase isso é ",[21,106,107],{},"emailRedirectTo"," em ",[21,110,111],{},"signUp"," e ",[21,114,115],{},"signInWithOtp",", e\n",[21,118,90],{},[21,120,121],{},"resetPasswordForEmail",[21,123,124],{},"signInWithOAuth",". Depois o Supabase\nAuth decide em\n",[58,127,130],{"href":128,"rel":129},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fauth\u002Fblob\u002Fmaster\u002Finternal\u002Futilities\u002Frequest.go",[62],"uma função curta",",\nnesta ordem:",[133,134,135,142,148],"ol",{},[136,137,138,141],"li",{},[42,139,140],{},"O endereço que o seu app pediu",", se ele bate com uma entrada da sua lista\nRedirect URLs ou fica no mesmo domínio da sua Site URL.",[136,143,144,147],{},[42,145,146],{},"O endereço da página de onde veio a requisição",", do jeito que o\nnavegador informou, pela mesma regra.",[136,149,150,153],{},[42,151,152],{},"Senão, a Site URL."," O Supabase não dá erro nenhum, e o console do seu\napp não mostra nada.",[10,155,156,157,162,163,165],{},"Ele toma essa decisão quando o e-mail é enviado, e o endereço escolhido entra\nno link. Quando alguém abre o link, o Supabase confere esse endereço de novo\ncom as suas configurações do jeito que estão naquele momento. A própria\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],"resposta de solução de problemas","\ndo Supabase resume a regra numa frase: para a opção ",[21,164,90],{}," funcionar,\nvocê precisa colocar a URL exata na configuração Redirect URLs.",[167,168],"diagram",{"alt":169,"caption":170,"src":171},"Um link de e-mail chega a uma placa de sinalização com três setas. As duas primeiras, a do endereço que o app pediu e a da página de onde veio a requisição, são conferidas cada uma contra uma lista e riscadas. A terceira seta, a Site URL, leva a pessoa a um notebook com a tela apagada e um X vermelho.","O Supabase tenta o endereço que o seu app pediu, depois a página de onde veio a requisição. Quando nenhum dos dois está na sua lista, quem decide é a Site URL.","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fthree-tries-1600x760.png",[10,173,174,175,179],{},"A mesma configuração decide para onde o \"Sign in with Google\" devolve as\npessoas, então um botão do Google que cai em localhost tem a mesma causa. Um\nbotão do Google que para antes, numa página que diz \"Unsupported provider:\nprovider is not enabled\", é outra coisa:\n",[58,176,178],{"href":177},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","uma chave no Supabase e uma lista no Google",".",[47,181,183],{"id":182},"por-que-você-não-viu-isso-antes-do-lançamento","Por que você não viu isso antes do lançamento",[10,185,186],{},"Porque os dois jeitos com que você testou nunca chegam à Site URL.",[188,189,190,196,202],"ul",{},[136,191,192,195],{},[42,193,194],{},"O login com senha acontece dentro da página."," Não tem link de e-mail nem\npassagem pela porta do Supabase, então ninguém lê a placa.",[136,197,198,201],{},[42,199,200],{},"Se você constrói com Cursor ou Claude Code e o seu servidor de\ndesenvolvimento estava rodando na porta 3000"," quando você testou o e-mail, o\nlink abriu a sua própria cópia local e pareceu funcionar.",[136,203,204,207,208,213,214,217],{},[42,205,206],{},"No backend integrado do Lovable talvez isso nunca aconteça com você."," A\n",[58,209,212],{"href":210,"rel":211},"https:\u002F\u002Fdocs.lovable.dev\u002Ffeatures\u002Fauthentication",[62],"documentação de autenticação","\ndo Lovable diz que ele coloca a Site URL no seu endereço publicado em\n",[21,215,216],{},"lovable.app"," quando você publica, e que adiciona um domínio próprio às\nredirect URLs quando você o conecta. A mesma página diz que os apps que usam\no seu próprio projeto do Supabase não recebem atualizações automáticas.",[47,219,221],{"id":220},"a-conta-está-confirmada-mesmo-a-página-não-tendo-carregado","A conta está confirmada mesmo a página não tendo carregado?",[10,223,224],{},"Sim, numa confirmação de cadastro. O Supabase confirma primeiro e só depois\nmanda o navegador adiante.",[10,226,227,228,233,234,179],{},"No\n",[58,229,232],{"href":230,"rel":231},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fauth\u002Fblob\u002Fmaster\u002Finternal\u002Fapi\u002Fverify.go",[62],"código que trata o link",",\na conta é confirmada antes de o redirecionamento sair. A página que não carrega\nchega com o trabalho já feito. Então diga à pessoa que ela pode entrar no seu\nsite no ar com a senha que escolheu. Apertar o mesmo e-mail de novo não\nadianta: o link funciona uma vez, e o segundo aperto responde\n",[58,235,237],{"href":236},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","\"Email link is invalid or has expired\"",[10,239,240],{},"Um magic link ou uma redefinição de senha é diferente. Esse login foi para\nlocalhost e ficou lá, então depois que você corrigir as configurações a pessoa\nprecisa de um e-mail novo.",[47,242,244],{"id":243},"como-corrigir-o-redirecionamento-do-supabase-para-localhost","Como corrigir o redirecionamento do Supabase para localhost",[10,246,247,248,251,252,255],{},"Troque a Site URL e depois liste os outros endereços para onde você manda as\npessoas. Os dois ficam na página ",[42,249,250],{},"URL Configuration",", em ",[42,253,254],{},"Authentication",",\nno painel do Supabase.",[10,257,258,265,268,269,271,272,276,277,280],{},[42,259,260,261,264],{},"Coloque a Site URL no seu endereço no ar, com ",[21,262,263],{},"https:\u002F\u002F"," na frente.",[21,266,267],{},"https:\u002F\u002Fyourapp.com",", escrito por inteiro. Sem o ",[21,270,263],{},", o Supabase lê o\nendereço como um caminho dentro do próprio endereço dele, e a pessoa cai no seu\nprojeto do Supabase com\n",[58,273,275],{"href":274},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\"",". A partir\ndaí qualquer endereço desse domínio é aceito em qualquer caminho sem entrada na\nlista, então ",[21,278,279],{},"https:\u002F\u002Fyourapp.com\u002Fwelcome"," funciona assim que a Site URL\nestiver certa.",[10,282,283,286,287,290,291,294,295,298],{},[42,284,285],{},"Adicione os outros endereços em Redirect URLs."," A versão com ",[21,288,289],{},"www"," se as\npessoas a usam, o endereço publicado no builder (",[21,292,293],{},"https:\u002F\u002Fyourapp.lovable.app",",\npor exemplo) se as pessoas se cadastram ali, e nada mais. Uma entrada é um\npadrão, então ",[21,296,297],{},"https:\u002F\u002Fyourapp.com\u002F**"," cobre todas as páginas desse único\ndomínio.",[10,300,301,304,305,308,309,311,312,315,316,319],{},[42,302,303],{},"Confira o que o seu código pede."," Se ele passa ",[21,306,307],{},"window.location.origin",", o\nendereço é aquele em que a página foi aberta, e todo endereço que isso possa\ngerar tem que estar no domínio da sua Site URL ou na lista. Compare letra por\nletra: com ",[21,310,289],{}," ou sem, com ",[21,313,314],{},"https"," ou sem. Uma entrada sem ",[21,317,318],{},"\u002F**"," no final\nbate com aquele endereço exato e com nada abaixo dele.",[10,321,322,325,326,329,330,332,333,335,336,339],{},[42,323,324],{},"Confira os seus modelos de e-mail."," Um modelo que monta o próprio link com\n",[21,327,328],{},"{{ .SiteURL }}"," manda todo mundo para a Site URL, não importa o que o seu app\npediu. O guia de redirecionamentos do Supabase diz que, ao usar a opção\n",[21,331,90],{},", talvez você precise substituir ",[21,334,328],{}," por\n",[21,337,338],{},"{{ .RedirectTo }}"," nos seus modelos de e-mail.",[341,342,343,356],"table",{},[344,345,346],"thead",{},[347,348,349,353],"tr",{},[350,351,352],"th",{},"O que você vê",[350,354,355],{},"O que mudar",[357,358,359,371,379,387,398],"tbody",{},[347,360,361,368],{},[362,363,364,365],"td",{},"Todo link abre ",[21,366,367],{},"localhost:3000",[362,369,370],{},"A Site URL",[347,372,373,376],{},[362,374,375],{},"Os links abrem a sua Site URL em vez do endereço que o seu código pediu",[362,377,378],{},"Adicione esse endereço em Redirect URLs, letra por letra",[347,380,381,384],{},[362,382,383],{},"O domínio no ar funciona e o endereço publicado no builder não",[362,385,386],{},"Adicione o endereço publicado em Redirect URLs",[347,388,389,392],{},[362,390,391],{},"Um link abre o seu endereço do Supabase com \"No API key found in request\"",[362,393,394,395,397],{},"Coloque ",[21,396,263],{}," na Site URL",[347,399,400,403],{},[362,401,402],{},"O endereço que o seu app pede está na lista e o link continua ignorando",[362,404,405,406,408],{},"O ",[21,407,328],{}," do modelo de e-mail",[10,410,411,412,414],{},"Depois cadastre-se de novo com um endereço que você ainda não usou. Um e-mail\nenviado antes da correção com o link padrão do Supabase, e aberto dentro da\nhora dele, agora chega ao seu site no ar, porque o Supabase confere o endereço\nde novo quando o link é aberto. Isso vale a menos que ",[21,413,36],{},"\ncontinue na sua lista.",[47,416,418],{"id":417},"quais-redirect-urls-é-seguro-permitir","Quais Redirect URLs é seguro permitir?",[10,420,421],{},"Os endereços exatos que são seus. Um curinga serve para deploys de\npré-visualização, e só limitado ao seu próprio time ou projeto.",[10,423,424,425,428],{},"O guia de redirecionamentos do Supabase diz isso com clareza: o \"globstar\"\n(",[21,426,427],{},"**",") é útil para desenvolvimento local e endereços de pré-visualização, mas\nem produção ele recomenda definir o caminho de redirecionamento exato da sua\nSite URL.",[10,430,431,432,437,438,441],{},"O motivo é o que viaja junto com a pessoa. No fluxo padrão, o Supabase escreve\na nova sessão no endereço para onde a manda:\n",[58,433,436],{"href":434,"rel":435},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fauth\u002Fblob\u002Fmaster\u002Finternal\u002Ftokens\u002Fservice.go",[62],"o código que monta isso","\nacrescenta ",[21,439,440],{},"#access_token=…&refresh_token=…"," ao endereço de redirecionamento.\nQualquer página nesse endereço pode ler esses dois valores, e com eles ela é\naquele usuário. Na placa, é a seta que decide quem recebe a chave.",[10,443,444],{},"Então uma entrada que cobre um endereço controlado por outra pessoa é um\ncaminho para dentro das contas dos seus usuários. Qualquer um pode pedir ao seu\nprojeto que mande por e-mail um link de login para um dos seus usuários, usando\na chave pública que está no seu app de propósito, e indicar a própria página\ncomo destino. O e-mail que chega é mesmo do seu app. O fluxo PKCE não muda\nisso, porque quem escreveu esse link começou o login, e o PKCE entrega a sessão\na quem começou.",[10,446,447],{},"Os padrões que cobrem endereços que outras pessoas podem criar:",[188,449,450,458,469],{},[136,451,452,457],{},[42,453,454,456],{},[21,455,427],{}," sozinho"," cobre todos os endereços que existem.",[136,459,460,465,466,179],{},[42,461,462],{},[21,463,464],{},"https:\u002F\u002F*.vercel.app\u002F**"," cobre todos os deploys da Vercel na internet,\ne qualquer um pode criar um. O próprio exemplo do Supabase leva o seu time:\n",[21,467,468],{},"https:\u002F\u002F*-\u003Cteam-or-account-slug>.vercel.app\u002F**",[136,470,471,480,481,179],{},[42,472,473,476,477],{},[21,474,475],{},"https:\u002F\u002F*.lovable.app\u002F**",", ",[21,478,479],{},"https:\u002F\u002F*.netlify.app\u002F**"," e a mesma forma\nno domínio de qualquer builder fazem o mesmo para esse builder. O exemplo do\nSupabase para a Netlify também é limitado:\n",[21,482,483],{},"https:\u002F\u002F**--my_org.netlify.app\u002F**",[167,485],{"alt":486,"caption":487,"src":488},"Duas placas de sinalização. À esquerda a lista tem um endereço exato, um link forjado que aponta para outro lugar é recusado, e a pessoa chega à própria casa com a chave. À direita a lista tem um curinga, o link forjado é aceito, e a chave vai para outra casa com contorno vermelho.","Uma entrada exata manda um link forjado para casa. Um curinga que cobre os apps dos outros deixa ele entregar o login a eles.","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fwho-gets-the-key-1600x760.png",[10,490,491],{},"Se você acabou de resolver isso colando um curinga, olhe a lista de novo hoje.",[10,493,494,495,179],{},"O lançamento também é a hora em que as outras configurações que só importam em\nprodução são olhadas. O nosso scan gratuito lê o seu app no ar de fora e mostra\no que um estranho consegue alcançar: tabelas que respondem a qualquer um,\nchaves secretas no código que o seu app envia, cabeçalhos que faltam, o\ncertificado. Leva uns 20 segundos e não precisa de conta:\n",[58,496,498],{"href":497},"\u002Fsecurity-scanner","escaneie o seu app",[47,500,502],{"id":501},"acompanhar-o-app-no-ar-depois-do-lançamento","Acompanhar o app no ar depois do lançamento",[10,504,505],{},"Essa configuração se corrige uma vez. O que o seu app envia aos visitantes muda\na cada deploy, e essa parte dá para vigiar de fora.",[10,507,508],{},[42,509,510,514],{},[58,511,513],{"href":512},"\u002Fwebsite-monitoring","Reeve Monitor"," continua verificando o seu app no ar:",[188,516,517,520,523,526],{},[136,518,519],{},"se ele está no ar, a cada 60 segundos, para separar \"o link não funciona\" de \"o site caiu\"",[136,521,522],{},"as nove verificações a cada hora, em até três apps, incluindo chaves secretas no código que o seu app envia aos visitantes",[136,524,525],{},"uma mensagem quando um resultado muda, para que um problema que sai num deploy posterior chegue até você sem você precisar ir olhar",[136,527,528],{},"um relatório mensal, em linguagem simples, do que ele viu",[10,530,531],{},[42,532,533,537],{},[58,534,536],{"href":535},"\u002Fsupabase-backups","Reeve Care"," guarda uma cópia do seu banco de dados\nSupabase, contas incluídas:",[188,539,540,543,546,549,552,555],{},[136,541,542],{},"uma cópia criptografada em uma programação, no armazenamento próprio da Reeve na UE, fora da sua conta do Supabase",[136,544,545],{},"o schema auth onde vivem as contas dos seus usuários, para que elas voltem com todo o resto",[136,547,548],{},"cada cópia verificada antes de contar, contando as linhas de cada tabela",[136,550,551],{},"seus arquivos enviados também, assim que você conectar uma credencial do Storage",[136,553,554],{},"uma restauração com um clique, com uma cópia de segurança do estado atual feita antes",[136,556,557],{},"tudo o que o Monitor faz",[47,559,561],{"id":560},"o-que-fazer-agora","O que fazer agora",[563,564,565],"key-takeaways",{},[188,566,567,572,578,590,593],{},[136,568,569,570,179],{},"Coloque a Site URL da página URL Configuration no seu endereço no ar, com ",[21,571,263],{},[136,573,574,575,577],{},"Adicione em Redirect URLs os outros endereços exatos para onde você manda as pessoas, como a versão com ",[21,576,289],{}," e o endereço publicado no builder.",[136,579,580,581,583,584,586,587,589],{},"Garanta que todo endereço que o seu código passa como ",[21,582,107],{}," ou ",[21,585,90],{}," está na lista, e use ",[21,588,338],{}," nos modelos que devem segui-lo.",[136,591,592],{},"Diga a quem viu a página de localhost depois de se cadastrar que a conta está confirmada. Magic links e redefinições de senha precisam de um e-mail novo.",[136,594,595],{},"Limite os curingas às pré-visualizações do seu time, e nunca permita todos os apps do domínio de um builder.",[10,597,598,599,602,603,607],{},"Se as pessoas apertam o link novo e ouvem que ele expirou,\n",[58,600,601],{"href":236},"essa mensagem tem uma página própria",".\nO ",[58,604,606],{"href":605},"\u002Fchecklist","checklist de segurança de 10 minutos"," cobre o que costuma ficar\naberto num app recém-lançado.",{"title":23,"searchDepth":609,"depth":609,"links":610},3,[611,613,614,615,616,617,618,619],{"id":49,"depth":612,"text":50},2,{"id":97,"depth":612,"text":98},{"id":182,"depth":612,"text":183},{"id":220,"depth":612,"text":221},{"id":243,"depth":612,"text":244},{"id":417,"depth":612,"text":418},{"id":501,"depth":612,"text":502},{"id":560,"depth":612,"text":561},"Noções de segurança","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcover-1200x630.png","Uma placa de sinalização cuja seta acesa aponta para longe da casa aonde deveria levar, na direção de um notebook com a tela apagada.","Se o Supabase redireciona para localhost:3000, a Site URL nunca foi trocada ou o seu endereço falta em Redirect URLs. A solução, e o curinga a evitar.",false,"md",[627,630,633,636,639],{"q":628,"a":629},"Por que o meu e-mail de confirmação do Supabase abre localhost:3000?","Porque o Supabase mandou a pessoa para a Site URL do seu projeto, e a Site URL ainda é http:\u002F\u002Flocalhost:3000. O Supabase usa ela sempre que o endereço que o seu app pediu não está na lista Redirect URLs, ou quando o seu app não pediu nenhum. Troque na página URL Configuration, em Authentication.",{"q":631,"a":632},"A conta está confirmada se o link abriu localhost?","Sim, numa confirmação de cadastro. O Supabase confirma o endereço primeiro e só depois manda o navegador adiante, então a página que falha chega com o trabalho já feito. A pessoa pode entrar no seu site no ar com a senha que escolheu. Um magic link ou uma redefinição de senha precisa ser enviado de novo.",{"q":634,"a":635},"Adicionei o meu site em Redirect URLs e continua indo para localhost. Por quê?","A entrada tem que bater letra por letra com o endereço oferecido ao Supabase: com www ou sem, com https ou sem, e o caminho, porque uma entrada sem \u002F** no final só bate com aquele endereço exato. Se batem e o link ainda ignora, o seu modelo de e-mail monta o link com {{ .SiteURL }}. E corrija a própria Site URL, porque é para ela que todo o resto volta.",{"q":637,"a":638},"Preciso adicionar a minha Site URL na lista Redirect URLs?","Não. O Supabase aceita qualquer endereço no próprio domínio da Site URL sem entrada na lista, em qualquer caminho. A lista serve para os outros endereços: uma versão com www, o endereço publicado no builder, os deploys de pré-visualização.",{"q":640,"a":641},"Posso usar um curinga em Redirect URLs do Supabase?","Para pré-visualizações, limitado ao seu próprio time ou projeto, como nos exemplos do Supabase. Nunca um que cubra endereços que outras pessoas podem criar, como todos os apps em vercel.app ou lovable.app. O Supabase recomenda o endereço exato do seu site em produção.","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",[644,645,646,647,648,649,650],"supabase redirect to localhost","supabase redireciona para localhost","supabase magic link localhost 3000","supabase site url","supabase redirect urls","e-mail de confirmação supabase url errada","supabase redirect url curinga",{},true,"O Supabase redireciona links de e-mail para localhost:3000","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","2026-11-02",{"title":5,"description":623},"blog\u002Fsupabase-auth-redirects-to-localhost",[659,660,661],"Um redirecionamento do Supabase para localhost:3000 vem da Site URL da página URL Configuration. Um projeto começa com http:\u002F\u002Flocalhost:3000, e todo link de e-mail volta para ela quando o endereço que o seu app pediu não está na lista Redirect URLs.","Quem apertou um link de cadastro normalmente já está confirmado. O Supabase confirma a conta antes de mandar a pessoa adiante, então ela pode entrar no seu site de verdade.","Coloque a Site URL no seu endereço no ar e liste os endereços exatos que você usa. Um curinga tão amplo que cobre o app de outra pessoa deixa um link forjado mandar os seus usuários para lá, já com login feito.","tKb_wWoEPPFS0eglLCwYqWz8Gtz-lFgDPOEJH8546YM",[664,670,675,681,687,693,699,705,706,711,717,724,730,736,742,748,754,760,766,772,778,784,790,796,802,808,814,820,826,832,838,844,850,856,861,867,873,879,885,891,897,903,909,915,921,927,932,938,944,950,956,962,968,974,980,986,992,998,1004,1010,1016,1022,1028,1034,1040,1046,1052,1058,1064,1070,1076,1082,1088,1094,1100,1106,1112,1118,1124,1130,1136,1142,1148,1154,1159,1165,1171,1177,1182,1188],{"path":665,"title":666,"description":667,"published":668,"category":620,"image":669,"draft":624},"\u002Fblog\u002Fmax-client-connections-reached","Supabase \"max client connections reached\", explicado","Supabase \"max client connections reached\": o pooler não tem lugar para mais um cliente. A porta da sua string de conexão define o limite.","2026-11-09","\u002Fblog\u002Fmax-client-connections-reached\u002Fcard-800x500.png",{"path":177,"title":671,"description":672,"published":673,"category":620,"image":674,"draft":624},"Erro do Supabase: \"Unsupported provider: provider is not enabled\"","\"Unsupported provider: provider is not enabled\": o Google está desativado no seu projeto Supabase. Como ativar e corrigir o redirect_uri_mismatch.","2026-11-08","\u002Fblog\u002Funsupported-provider-provider-is-not-enabled\u002Fcard-800x500.png",{"path":676,"title":677,"description":678,"published":679,"category":620,"image":680,"draft":624},"\u002Fblog\u002Fviolates-foreign-key-constraint","Erro do Supabase \"violates foreign key constraint\" ao inserir","Supabase \"insert or update on table violates foreign key constraint\": sua linha aponta para uma linha que não existe. Qual, por quê, e como corrigir.","2026-11-07","\u002Fblog\u002Fviolates-foreign-key-constraint\u002Fcard-800x500.png",{"path":682,"title":683,"description":684,"published":685,"category":620,"image":686,"draft":624},"\u002Fblog\u002Fnull-value-violates-not-null-constraint","Erro do Supabase \"null value in column violates not-null constraint\"","Supabase \"null value in column violates not-null constraint\": uma coluna obrigatória chegou vazia. De onde veio o null, e como corrigir.","2026-11-06","\u002Fblog\u002Fnull-value-violates-not-null-constraint\u002Fcard-800x500.png",{"path":688,"title":689,"description":690,"published":691,"category":620,"image":692,"draft":624},"\u002Fblog\u002Fauth-session-missing","Supabase \"Auth session missing!\": para onde foi a sessão","\"Auth session missing!\" é o supabase-js sem achar nenhuma sessão logada e sem chegar a perguntar ao Supabase. Para onde foi a sessão, e a correção.","2026-11-05","\u002Fblog\u002Fauth-session-missing\u002Fcard-800x500.png",{"path":694,"title":695,"description":696,"published":697,"category":620,"image":698,"draft":624},"\u002Fblog\u002Finvalid-claim-missing-sub-claim","Supabase \"invalid claim: missing sub claim\": ninguém está logado","\"invalid claim: missing sub claim\": o Supabase Auth recebeu um token autêntico sem nenhum usuário, a chave do projeto no lugar de uma sessão.","2026-11-04","\u002Fblog\u002Finvalid-claim-missing-sub-claim\u002Fcard-800x500.png",{"path":700,"title":701,"description":702,"published":703,"category":620,"image":704,"draft":624},"\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function","\"Failed to send a request to the Edge Function\": a causa real","\"Failed to send a request to the Edge Function\": o navegador não recebeu uma resposta legível. O console dele diz por quê e se a sua função rodou.","2026-11-03","\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function\u002Fcard-800x500.png",{"path":654,"title":5,"description":623,"published":655,"category":620,"image":642,"draft":624},{"path":236,"title":707,"description":708,"published":709,"category":620,"image":710,"draft":624},"Supabase \"Email link is invalid or has expired\" num link novo","Num link enviado há um minuto, \"Email link is invalid or has expired\" no Supabase costuma significar que um filtro de e-mail o usou antes. Como resolver.","2026-11-01","\u002Fblog\u002Femail-link-is-invalid-or-has-expired\u002Fcard-800x500.png",{"path":712,"title":713,"description":714,"published":715,"category":620,"image":716,"draft":624},"\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout","Supabase \"canceling statement due to statement timeout\", explicado","Supabase \"canceling statement due to statement timeout\": uma consulta passou do limite do seu papel, 3 segundos para um visitante. Veja antes a política RLS.","2026-10-31","\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout\u002Fcard-800x500.png",{"path":718,"title":719,"description":720,"published":721,"category":722,"image":723,"draft":624},"\u002Fblog\u002Fdatabase-error-deleting-user","\"Database error deleting user\" no Supabase, e o que vai junto","\"Database error deleting user\" no Supabase: seu banco recusou a exclusão. O motivo está nos seus logs, e a correção decide o que mais é apagado.","2026-10-30","Backups","\u002Fblog\u002Fdatabase-error-deleting-user\u002Fcard-800x500.png",{"path":725,"title":726,"description":727,"published":728,"category":620,"image":729,"draft":624},"\u002Fblog\u002Fstripe-webhook-no-signatures-found","\"No signatures found matching the expected signature\" no Supabase","O webhook do Stripe numa Edge Function do Supabase diz \"No signatures found matching the expected signature\"? São duas causas. Continue verificando.","2026-10-29","\u002Fblog\u002Fstripe-webhook-no-signatures-found\u002Fcard-800x500.png",{"path":731,"title":732,"description":733,"published":734,"category":620,"image":735,"draft":624},"\u002Fblog\u002Fsupabase-invalid-login","\"Invalid login credentials\" no Supabase: as três causas","O Supabase diz \"Invalid login credentials\" para senha errada, e-mail desconhecido e conta Google. Como saber qual é, e por que é vago.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":737,"title":738,"description":739,"published":740,"category":620,"image":741,"draft":624},"\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code","\"Edge Function returned a non-2xx status code\": o erro real","\"Edge Function returned a non-2xx status code\" quer dizer que sua função do Supabase respondeu com um erro. Veja onde ler o erro real.","2026-10-27","\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code\u002Fcard-800x500.png",{"path":743,"title":744,"description":745,"published":746,"category":620,"image":747,"draft":624},"\u002Fblog\u002Fcertificate-not-trusted","Certificado não confiável: três causas além do vencimento","Certificado não confiável mesmo com a data certa? Ele cita outro endereço, assinou a si mesmo ou falta um elo na cadeia. Veja como saber qual.","2026-10-26","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",{"path":749,"title":750,"description":751,"published":752,"category":620,"image":753,"draft":624},"\u002Fblog\u002Finvalid-input-syntax-for-type-uuid","Supabase \"invalid input syntax for type uuid\": leia as aspas","Supabase \"invalid input syntax for type uuid\": seu app enviou algo que não é um id. Leia as aspas, segure a consulta, mantenha a coluna.","2026-10-25","\u002Fblog\u002Finvalid-input-syntax-for-type-uuid\u002Fcard-800x500.png",{"path":755,"title":756,"description":757,"published":758,"category":620,"image":759,"draft":624},"\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint","Supabase \"duplicate key value violates unique constraint\", explicado","Supabase \"duplicate key value violates unique constraint\": o valor já está em uso. Ache a coluna, escolha uma correção e tire o valor da tela.","2026-10-24","\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint\u002Fcard-800x500.png",{"path":761,"title":762,"description":763,"published":764,"category":620,"image":765,"draft":624},"\u002Fblog\u002Fsupabase-relation-does-not-exist","Supabase \"relation does not exist\" e a tabela está lá","Supabase \"relation does not exist\" ou PGRST205: nenhuma tabela tem esse nome nesse schema. Quatro verificações, e o que expor um schema abre.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":767,"title":768,"description":769,"published":770,"category":620,"image":771,"draft":624},"\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\" mostra os nomes de argumentos que seu app enviou. Compare-os com a função.","2026-10-22","\u002Fblog\u002Fsupabase-function-not-found\u002Fcard-800x500.png",{"path":773,"title":774,"description":775,"published":776,"category":620,"image":777,"draft":624},"\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\" costuma ser um nome que não bate. Quatro verificações e a linha que recarrega.","2026-10-21","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",{"path":779,"title":780,"description":781,"published":782,"category":620,"image":783,"draft":624},"\u002Fblog\u002Fsupabase-email-rate-limit-exceeded","Supabase \"Email Rate Limit Exceeded\": dois limites, um só código","Supabase \"Email Rate Limit Exceeded\" limita cada email que seu projeto envia: 2 por hora no remetente embutido. O que conta e como aumentar.","2026-10-20","\u002Fblog\u002Fsupabase-email-rate-limit-exceeded\u002Fcard-800x500.png",{"path":785,"title":786,"description":787,"published":788,"category":620,"image":789,"draft":624},"\u002Fblog\u002Fsupabase-users-logged-out","Supabase \"Invalid Refresh Token: Refresh Token Not Found\": 3 causas","Supabase \"Invalid Refresh Token: Refresh Token Not Found\" desconecta seus usuários. Três causas, e como o log do Auth separa cada uma.","2026-10-19","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcard-800x500.png",{"path":791,"title":792,"description":793,"published":794,"category":620,"image":795,"draft":624},"\u002Fblog\u002Fpermission-denied-for-schema-public","Supabase \"permission denied for schema public\": três causas","Supabase \"permission denied for schema public\" é um grant que falta no schema. O que o removeu, e a linha que o devolve.","2026-10-18","\u002Fblog\u002Fpermission-denied-for-schema-public\u002Fcard-800x500.png",{"path":797,"title":798,"description":799,"published":800,"category":620,"image":801,"draft":624},"\u002Fblog\u002Fsupabase-bucket-not-found","Supabase \"Bucket not found\": as três coisas que isso significa","Supabase \"Bucket not found\" é uma de três coisas: um link público para um bucket privado, um nome que não bate exatamente ou o projeto errado.","2026-10-17","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",{"path":803,"title":804,"description":805,"published":806,"category":620,"image":807,"draft":624},"\u002Fblog\u002Fsupabase-invalid-jwt","Supabase invalid JWT: qual chave parou de funcionar?","Um erro Supabase invalid JWT é o PGRST301: um token assinado não passou na verificação. Num projeto novo isso é a sessão, não a chave de API.","2026-10-16","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",{"path":809,"title":810,"description":811,"published":812,"category":620,"image":813,"draft":624},"\u002Fblog\u002Fsupabase-single-row-error","Supabase \"multiple (or no) rows returned\" quase sempre é nenhuma","O Supabase devolve PGRST116, \"JSON object requested, multiple (or no) rows returned\", quando a consulta não achou nada. Linha escondida parece ausente.","2026-10-15","\u002Fblog\u002Fsupabase-single-row-error\u002Fcard-800x500.png",{"path":815,"title":816,"description":817,"published":818,"category":620,"image":819,"draft":624},"\u002Fblog\u002Fdatabase-error-saving-new-user","\"Database error saving new user\" no Supabase: onde olhar","\"Database error saving new user\" quer dizer que algo preso ao seu cadastro no Supabase falhou e tudo foi desfeito. O erro real está nos seus logs.","2026-10-14","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcard-800x500.png",{"path":821,"title":822,"description":823,"published":824,"category":620,"image":825,"draft":624},"\u002Fblog\u002Fwhat-is-supabase","O que é Supabase? O banco de dados que seu builder escolheu","O que é Supabase: o banco de dados, o login e o armazenamento de arquivos do seu app. O Supabase cuida dos servidores; as regras das suas linhas são suas.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":827,"title":828,"description":829,"published":830,"category":620,"image":831,"draft":624},"\u002Fblog\u002Faws-access-key-exposed-in-frontend","Uma chave AWS exposta no seu frontend não é como uma chave OpenAI","Uma chave de acesso da AWS exposta no seu frontend lê e grava no seu armazenamento. A solução costuma ser uma presigned URL, não uma chave nova.","2026-10-12","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":833,"title":834,"description":835,"published":836,"category":620,"image":837,"draft":624},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" ao enviar","\"New row violates row-level security policy for table objects\" quer dizer que o seu envio não tem regra insert. Deixar o bucket público não cria nenhuma.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":839,"title":840,"description":841,"published":842,"category":620,"image":843,"draft":624},"\u002Fblog\u002Fbase44-security-scan","Scan de segurança do Base44: o que só ele enxerga","O scan de segurança do Base44 verifica sete tipos de problema por dentro. Esta é a metade que ele lê e mais ninguém, e a metade que ele nunca olha.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":845,"title":846,"description":847,"published":848,"category":620,"image":849,"draft":624},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Sua chave de API vazou. A ordem em que agir","Uma chave de API vazou e você não sabe o que fazer primeiro. Nem toda chave no seu frontend é um vazamento, e a ordem importa mais que a pressa.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":851,"title":852,"description":853,"published":854,"category":620,"image":855,"draft":624},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" sem desligar o RLS","\"Infinite recursion detected in policy for relation\" significa que a sua policy perguntou à tabela que ela protege. Veja como quebrar o círculo.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":274,"title":857,"description":858,"published":859,"category":620,"image":860,"draft":624},"\"No API key found in request\" no Supabase, e a correção errada","\"No API key found in request\" significa que sua requisição chegou ao Supabase sem chave. Quase toda resposta aponta para as regras do seu banco.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":862,"title":863,"description":864,"published":865,"category":620,"image":866,"draft":624},"\u002Fblog\u002Fis-base44-safe","O Base44 é seguro? O que vimos em 5.442 apps Base44","O Base44 é seguro? Rodamos nove verificações em 5.442 apps Base44 no ar. Quase todas tiraram B por motivos que o dono nunca escolheu.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":868,"title":869,"description":870,"published":871,"category":620,"image":872,"draft":624},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","Esconder uma chave de API: mova para uma Edge Function do Supabase","Esconder uma chave de API é tirá-la do navegador, e uma Edge Function do Supabase é o menor lugar para guardá-la. Dois passos em volta pesam mais.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":874,"title":875,"description":876,"published":877,"category":620,"image":878,"draft":624},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Seu arquivo .env está exposto? Os doze caminhos para testar","Seu arquivo .env está exposto no seu próprio servidor web? Doze endereços dizem isso em um minuto, e um acerto significa que tudo nele já é público.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":880,"title":881,"description":882,"published":883,"category":620,"image":884,"draft":624},"\u002Fblog\u002Fis-v0-safe","Segurança do v0: os 1.790 aplicativos v0 escaneados tiraram A","A segurança do v0 medida em 1.790 aplicativos v0 no ar: todos tiraram A. Só 17 citavam um banco de dados, e é sobretudo isso que esse A mede.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":886,"title":887,"description":888,"published":889,"category":620,"image":890,"draft":624},"\u002Fblog\u002Fis-bolt-safe","O Bolt é seguro? O que vimos em 1.123 aplicativos Bolt","O Bolt é seguro? Passamos 1.123 aplicativos Bolt no ar por nove verificações. A hospedagem saiu limpa. Os achados: chaves e tabelas abertas nos aplicativos.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":892,"title":893,"description":894,"published":895,"category":620,"image":896,"draft":624},"\u002Fblog\u002Fis-supabase-down-or-your-app","O Supabase caiu ou o problema é o seu app? Como saber","O Supabase caiu ou o problema é o seu app? Um projeto pausado, um banco cheio e um erro seu parecem iguais. Quatro verificações separam os casos.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":898,"title":899,"description":900,"published":901,"category":620,"image":902,"draft":624},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","O Supabase criptografa meus dados? Sim. Veja o que isso impede","O Supabase criptografa os dados? Sim: AES-256 em repouso, TLS em trânsito, SOC 2 e ISO 27001. O que cada um cobre, e o vazamento que nenhum deles impede.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":904,"title":905,"description":906,"published":907,"category":620,"image":908,"draft":624},"\u002Fblog\u002Fsupabase-free-plan-limits","O Supabase é gratuito? Sim, com estes limites e sem backups","Sim: o plano gratuito do Supabase vai até 500 MB de banco e 5 GB de egress, sem nenhum backup. O que para em cada limite e o que muda no Pro de $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":910,"title":911,"description":912,"published":913,"category":722,"image":914,"draft":624},"\u002Fblog\u002Ftest-your-supabase-backup","Teste o backup do seu Supabase antes do dia em que precisar","Como testar o backup do seu Supabase: restaurar num projeto de teste, contar as linhas, entrar e procurar a linha que falta num arquivo cortado.","2026-09-28","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":916,"title":917,"description":918,"published":919,"category":722,"image":920,"draft":624},"\u002Fblog\u002Fsupabase-backup-github-action","Backup grátis do Supabase com uma GitHub Action, e a pegadinha","Um backup do Supabase com GitHub Action é grátis e serve para muitos apps. O workflow, a connection string certa e o egress de cada execução.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":922,"title":923,"description":924,"published":925,"category":722,"image":926,"draft":624},"\u002Fblog\u002Fdownload-your-supabase-backup","Por que você não consegue baixar seu backup do Supabase","Você não consegue baixar seu backup do Supabase num projeto atual, porque a cópia diária é um snapshot físico. Como conferir e como ter uma cópia só sua.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":928,"title":929,"description":930,"published":925,"category":620,"image":931,"draft":624},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": o grant que falta","A partir de 30 de outubro, uma tabela nova no Supabase responde \"permission denied for table\" até receber um grant. O e-mail mostra só metade.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":933,"title":934,"description":935,"published":936,"category":620,"image":937,"draft":624},"\u002Fblog\u002Fopen-api-endpoint-exposed","Um endpoint de API aberto é um problema? Leia o JSON","Seu scan apontou um endpoint de API aberto. Se isso importa depende do que voltou, e a maioria dos que encontramos era da própria plataforma.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":939,"title":940,"description":941,"published":942,"category":620,"image":943,"draft":624},"\u002Fblog\u002Flovable-security-scan","Escaneamento de segurança do Lovable: o que ele não prova","Escaneamento de segurança do Lovable: o que o Quick scan e o Deep scan checam, quando cada um roda, e a única coisa que nenhum escaneamento por dentro prova.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":945,"title":946,"description":947,"published":948,"category":722,"image":949,"draft":624},"\u002Fblog\u002Fsupabase-backup-auth-users","Por que seu dump do Supabase não tem usuários dentro","Rode supabase db dump sozinho e você recebe a forma do seu banco e nenhuma das linhas dele, sem o schema auth onde seus usuários moram.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":951,"title":952,"description":953,"published":954,"category":620,"image":955,"draft":624},"\u002Fblog\u002Fdomain-and-certificate-expiry","Domínio expirado, site fora do ar: o que acontece agora","Seu domínio expirou e seu site está fora do ar. O relógio que começa a correr, por que o certificado é o problema menor, e como conferir os dois.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":957,"title":958,"description":959,"published":960,"category":620,"image":961,"draft":624},"\u002Fblog\u002Fis-lovable-safe","O Lovable é seguro? O que vimos em 18.554 aplicativos Lovable","O Lovable é seguro? Passamos 18.554 aplicativos Lovable no ar por nove verificações. A plataforma foi a mais limpa de cinco. Os achados estavam nos aplicativos.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":963,"title":964,"description":965,"published":966,"category":620,"image":967,"draft":624},"\u002Fblog\u002Fvibe-coded-app-security-checklist","O checklist de segurança do vibe coding, em nove verificações","Um checklist de segurança do vibe coding com nove itens, cada um verificável no seu app de fora por qualquer pessoa, e cada um com um teste de uma linha.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":969,"title":970,"description":971,"published":972,"category":620,"image":973,"draft":624},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Uma chave secreta da Stripe no frontend pode mover dinheiro","Uma chave secreta da Stripe exposta no seu frontend pode reembolsar, cobrar e ler cada ficha de cliente que você tem. Sua chave pk_live_ é que deve estar aí.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":975,"title":976,"description":977,"published":978,"category":620,"image":979,"draft":624},"\u002Fblog\u002Fvite-and-next-public-env-vars","Variáveis de ambiente do Vite expostas: o prefixo diz publique isto","Variáveis de ambiente do Vite expostas no seu app: fizeram o que o prefixo pediu. VITE_ e NEXT_PUBLIC_ significam publique isto, e a IA nunca soube o custo.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":981,"title":982,"description":983,"published":984,"category":620,"image":985,"draft":624},"\u002Fblog\u002Fbase44-source-maps","Segurança no Base44: o que um scan aponta e o que é seu para corrigir","Segurança no Base44 em 5.438 apps escaneados: três achados em quase todos são da plataforma, o source map é o selo do Base44, e a sua parte é uma lista curta.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":987,"title":988,"description":989,"published":990,"category":620,"image":991,"draft":624},"\u002Fblog\u002Fis-cursor-ai-safe","O Cursor AI é seguro? O editor, o código e o app que você publicou","O Cursor AI é seguro? Três perguntas em uma busca: o que o Cursor guarda, o que o código que ele escreve erra, e se o app que você publicou está aberto.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":993,"title":994,"description":995,"published":996,"category":620,"image":997,"draft":624},"\u002Fblog\u002Fis-replit-safe","O Replit é seguro? O que vimos em 3.042 aplicativos Replit no ar","O Replit é seguro? Passamos 3.042 aplicativos Replit no ar por nove verificações externas. Os achados estavam no aplicativo publicado, não no host.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":999,"title":1000,"description":1001,"published":1002,"category":722,"image":1003,"draft":624},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: sua cópia do banco não tem nenhum arquivo","Um Supabase storage backup é uma tarefa à parte. Os backups do banco guardam a lista dos seus arquivos e nenhum deles, então cada upload fica quebrado.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":1005,"title":1006,"description":1007,"published":1008,"category":722,"image":1009,"draft":624},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery do Supabase: preço e limites","O point-in-time recovery do Supabase rebobina seu banco para qualquer segundo da última semana. Custa $100 por mês além do Pro e cobre só o banco.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":1011,"title":1012,"description":1013,"published":1014,"category":722,"image":1015,"draft":624},"\u002Fblog\u002Fsupabase-project-paused-recover","Projeto Supabase pausado? Seus dados continuam lá","O Supabase pausou seu projeto depois de uma semana sem atividade. Nada foi apagado, Restaurar fica ao lado do nome e você tem um ano antes disso mudar.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":1017,"title":1018,"description":1019,"published":1020,"category":620,"image":1021,"draft":624},"\u002Fblog\u002Fsafest-ai-app-builder","Qual builder de apps com IA é mais seguro? 30.998 apps testados","Qual builder de apps com IA é mais seguro? Escaneamos 30.998 apps no ar do Lovable, Base44, Replit, v0 e Bolt. O builder não é o que decide sua nota.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":1023,"title":1024,"description":1025,"published":1026,"category":620,"image":1027,"draft":624},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Ative Row Level Security em toda tabela do Supabase e comprove","Ativar Row Level Security no Supabase sem política fecha a tabela por completo. Uma política sem a chave ligada não faz nada. Aqui está o SQL, e o teste.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":1029,"title":1030,"description":1031,"published":1032,"category":620,"image":1033,"draft":624},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": o que o aviso não vê","O Supabase marca \"RLS disabled in public\" como erro. Ele não diz nada sobre a política de leitura que deixa a sua tabela igualmente aberta.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":1035,"title":1036,"description":1037,"published":1038,"category":620,"image":1039,"draft":624},"\u002Fblog\u002Frotate-supabase-service-role-key","Como rotacionar uma chave service_role do Supabase vazada","O Supabase manda fechar o vazamento primeiro. Outros guias mandam rotacionar agora. O que vale depende de para onde a sua chave service_role vazou.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":1041,"title":1042,"description":1043,"published":1044,"category":620,"image":1045,"draft":624},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Scanners de segurança para vibe coding comparados, o nosso incluído","O melhor scanner de segurança para vibe coding depende de três perguntas que nenhuma lista de recursos responde. Oito ferramentas comparadas, com preços.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":1047,"title":1048,"description":1049,"published":1050,"category":620,"image":1051,"draft":624},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: faça você mesmo as cinco verificações","Um Supabase security checker lê o seu app publicado em vez das configurações do projeto. Aqui estão as cinco verificações e como fazer cada uma sozinho.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":1053,"title":1054,"description":1055,"published":1056,"category":620,"image":1057,"draft":624},"\u002Fblog\u002Fvibe-coding-security-scanner","Scanner de segurança para vibe coding: o que ele não vê","Um scanner de segurança para vibe coding lê seu app no ar, de fora. O que isso cobre, as quatro coisas que ele não consegue ver e como ler o resultado.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":1059,"title":1060,"description":1061,"published":1062,"category":620,"image":1063,"draft":624},"\u002Fblog\u002Fmissing-security-headers","Cabeçalhos de segurança faltando: quando isso importa","Cabeçalhos de segurança faltando é o achado que nosso scanner mais imprime. Contra o que eles protegem e quando são a linha menos urgente do relatório.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":1065,"title":1066,"description":1067,"published":1068,"category":620,"image":1069,"draft":624},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Sua chave de API da OpenAI está exposta no frontend. Troque-a.","Uma chave de API da OpenAI exposta no frontend não pode ser presa a um domínio. Troque-a hoje, mova a chamada para o seu servidor e limite o gasto.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1071,"title":1072,"description":1073,"published":1074,"category":620,"image":1075,"draft":624},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Chave de API exposta no frontend: o que 30.998 apps entregam","Uma chave de API exposta no seu frontend costuma ser uma chave do Google Maps. Escaneamos 30.998 apps vibe-coded e contamos quais segredos vazam de verdade.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":1077,"title":1078,"description":1079,"published":1080,"category":722,"image":1081,"draft":624},"\u002Fblog\u002Fsupabase-backup-tools-compared","Ferramentas de backup do Supabase comparadas, a nossa incluída","Quatro tipos de ferramenta de backup do Supabase, o que cada uma copia de verdade e quando uma GitHub Action gratuita ganha de pagar, nós inclusive.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":1083,"title":1084,"description":1085,"published":1086,"category":620,"image":1087,"draft":624},"\u002Fblog\u002Freplit-secrets-explained","Como usar secrets no Replit, e o que ainda assim é publicado","Como usar secrets no Replit: adicionar um, ler de volta e resolver as duas causas do undefined. E as chaves que a ferramenta Secrets não consegue proteger.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":1089,"title":1090,"description":1091,"published":1092,"category":722,"image":1093,"draft":624},"\u002Fblog\u002Fback-up-supabase-free-tier","Backups do plano gratuito do Supabase: como fazer sem terminal","No plano gratuito do Supabase não existe backup nenhum: a cópia é você que faz. Como fazer uma pelo painel e o que a rota do CSV deixa para trás.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":1095,"title":1096,"description":1097,"published":1098,"category":620,"image":1099,"draft":624},"\u002Fblog\u002Fis-supabase-secure","O Supabase é seguro? É. Seu projeto é outra pergunta","O Supabase é seguro? A plataforma é auditada, criptografada e passa por pentests. A documentação deles diz onde isso termina e começam suas configurações.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":1101,"title":1102,"description":1103,"published":1104,"category":620,"image":1105,"draft":624},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Onde ficam as chaves de API do Supabase: anon, service_role e URL","A URL do projeto, a chave anon e a chave service_role ficam todas numa página do painel. Aqui está onde ela fica, e qual dos quatro valores vai no seu app.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":1107,"title":1108,"description":1109,"published":1110,"category":620,"image":1111,"draft":624},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy no Supabase. E agora?","\"New row violates row-level security policy\" significa que o Supabase recusou uma escrita. O conserto rápido reabre a tabela para qualquer um.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":1113,"title":1114,"description":1115,"published":1116,"category":620,"image":1117,"draft":624},"\u002Fblog\u002Fcors-wildcard-security-risk","Um curinga CORS é um risco de segurança? Quase nunca.","Um curinga CORS é um risco de segurança? Em geral é o padrão do seu builder e não entrega nada que o seu servidor já não desse a qualquer um que pedisse.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":1119,"title":1120,"description":1121,"published":1122,"category":722,"image":1123,"draft":624},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Branching do Supabase não é backup. Ele só anda para a frente.","Por que o branching do Supabase não é backup: um branch começa sem os seus dados e um merge só leva o esquema. Para que ele serve e o que usar no lugar.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":1125,"title":1126,"description":1127,"published":1128,"category":722,"image":1129,"draft":624},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Como restaurar um backup do Supabase, e o que quebra depois","Como restaurar um backup do Supabase pelo painel ou por um arquivo de dump, o que a restauração substitui e por que o seu app pode continuar quebrado no fim.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":1131,"title":1132,"description":1133,"published":1134,"category":620,"image":1135,"draft":624},"\u002Fblog\u002Fsupabase-storage-bucket-public","Seu bucket do Supabase Storage é público. Isso é um problema?","Um bucket público do Supabase Storage significa que quem tem a URL de um arquivo pode abri-lo. Não significa que alguém possa listar o que está lá dentro.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":1137,"title":1138,"description":1139,"published":1140,"category":620,"image":1141,"draft":624},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Uma chave de API do Google no frontend é um problema?","Uma chave de API do Google exposta no seu frontend é a chave que nosso scanner mais encontra, e quase sempre está tudo bem. Um ajuste gratuito decide isso.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1143,"title":1144,"description":1145,"published":1146,"category":722,"image":1147,"draft":624},"\u002Fblog\u002Fai-agent-deleted-my-database","Um agente de IA apagou meus dados do Supabase. O que eu recupero?","Um agente de IA apagou dados do seu banco. O que você recupera já estava decidido antes de ele rodar, e os próximos minutos decidem o resto.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":1149,"title":1150,"description":1151,"published":1152,"category":620,"image":1153,"draft":624},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Qualquer um consegue ler seu banco Supabase? Testamos 3.680 apps","Qualquer um consegue ler seu banco de dados Supabase sem fazer login? Escaneamos 30.998 apps no ar criadas com builders de IA e medimos quantas dizem que sim.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":1155,"title":1156,"description":1157,"published":1152,"category":620,"image":1158,"draft":624},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source maps expostos: seu app está publicando o código original","Um source map exposto deixa qualquer um ler o código original do seu app, comentários incluídos. A verificação de 30 segundos e o que importa de verdade.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":1160,"title":1161,"description":1162,"published":1163,"category":620,"image":1164,"draft":624},"\u002Fblog\u002Fsupabase-new-api-keys","Supabase publishable key: é a mesma coisa que a anon key?","O Supabase trocou anon e service_role por chaves publicáveis e secretas. Qual delas pertence ao seu app e qual nunca deve estar lá?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":1166,"title":1167,"description":1168,"published":1169,"category":722,"image":1170,"draft":624},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","O Supabase faz backup do meu banco de dados? Depende do plano.","O Supabase faz backup do seu banco de dados? Todo dia nos planos pagos, e nada no gratuito. Como descobrir o que você tem e o que essa cópia não cobre.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":1172,"title":1173,"description":1174,"published":1175,"category":620,"image":1176,"draft":624},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","O Supabase Row Level Security está ligado. A tabela continua pública.","Ligar o Supabase Row Level Security não protege uma tabela. Quem protege são as políticas, e a que consertou o seu app pode deixar qualquer um entrar.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":1178,"title":1179,"description":1180,"published":1175,"category":722,"image":1181,"draft":624},"\u002Fblog\u002Fversion-history-is-not-a-backup","O histórico de versões não é backup. Ele não desfaz um delete.","Lovable e Bolt guardam um histórico de versões do seu código. Seu banco de dados é um serviço à parte, e voltar atrás não traz os seus dados de volta.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":1183,"title":1184,"description":1185,"published":1186,"category":722,"image":1187,"draft":624},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Três formas de fazer backup de um banco Supabase, e o que falta","O painel, o pg_dump e um serviço gerenciado. O que cada um salva de verdade, o que deixa de fora sem avisar e qual sobrevive a perder a conta.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":1189,"title":1190,"description":1191,"published":1186,"category":620,"image":1192,"draft":624},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Quais chaves de API são seguras no navegador e quais não são","Sua chave anon do Supabase foi feita para ser pública. Sua chave service_role não, e ela ignora todas as regras que você criar. Como diferenciar as duas.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1794213648825]