"Variável de ambiente: a coisa que quebra o deploy de todo mundo e ninguém explicou"
Variável de ambiente mora em três lugares, e o deploy quebra quando um está vazio. O checklist de 20 minutos pra conferir os três e tirar segredo do código.
"Quando você faz deploy para a Netlify, Vercel ou outro serviço, precisa configurar essas variáveis manualmente — e é aí que a maioria das pessoas esquece ou erra."
Isso é de um blog brasileiro que vive de consertar app feito no Lovable. Não é estatística, é o que quem conserta vê, e bate com o que eu vejo: funciona no preview, morre no ar, e a causa é uma variável de ambiente que ficou pra trás.
Já traduzi o que ela é: um valor guardado fora do código, tipo senha, que muda conforme onde o app roda. O que ninguém explicou é por que ela some. E a resposta é que uma variável de ambiente não mora num lugar. Mora em três. O deploy quebra quando um dos três está vazio.
Os três lugares onde a mesma variável mora
- Na sua máquina. Um arquivo chamado
.envna pasta do projeto, com linhas comoSTRIPE_SECRET_KEY=sk_live_.... É o que faz o app funcionar emlocalhost. - No painel da plataforma. Vercel, Netlify, o Secrets do Lovable. É o que faz o app funcionar no ar. Ninguém copia o arquivo 1 pra cá sozinho. Você publica o código; o valor fica na sua máquina.
- Dentro do código. Aqui mora só o nome (
STRIPE_SECRET_KEY), nunca o valor. O código diz "use a chave que estiver cadastrada com esse nome", e cada lugar entrega a sua.
O erro clássico é achar que o lugar 1 e o 2 são a mesma coisa. Não são. E a documentação da Netlify avisa: "mudanças em variáveis de ambiente exigem um build e deploy pra valer". Cadastrou e não republicou é o mesmo que não ter cadastrado. A Vercel tem a mesma regra.
O que nunca vai pro código
A regra vem de um documento de 2011 que todo programador conhece e ninguém traduziu, o Twelve-Factor App: configuração é "tudo que tende a variar entre um deploy e outro", e o teste é se "o código poderia virar aberto a qualquer momento sem comprometer nenhuma credencial".
A documentação do Vite (a ferramenta por baixo de projeto Lovable) separa: .env é lido sempre; .env.local é "só local" e fica fora do git. No projeto Lovable o .env vai pro repositório de propósito, porque só carrega chave pública (prefixo VITE_). Chave secreta não entra nesse arquivo nunca. Se entrou, está no GitHub, e apagar a linha não resolve: o histórico guarda.
Você não precisa ler o valor pra saber se é secreto. Basta o nome:
| Começa com | É | Onde pode estar |
|---|---|---|
VITE_, NEXT_PUBLIC_, pk_, sb_publishable_ |
pública | navegador, .env, painel |
sk_live_, sk_test_, sb_secret_, service_role, -----BEGIN |
secreta | só o painel (e o .env.local da sua máquina) |
O Supabase, banco por trás do Lovable, é direto sobre a secreta: "nunca coloque uma num navegador, num app distribuído ou no controle de versão", e avisa que anon e service_role saem de linha até o fim de 2026, virando sb_publishable_ e sb_secret_. O Stripe manda procurar sk_live_ no código e, se achar, "assumir que foi exposta e comprometida".
O checklist: 20 minutos, hoje
1. Faça o inventário. Peça pra IA:
"Crie um arquivo
.env.examplecom o nome de cada variável de ambiente que o projeto lê, uma por linha, com o valor em branco e um comentário dizendo pra que serve. Não inclua nenhum valor real. Não mude mais nada."
Esse arquivo pode ir pro código: só tem nomes.
2. Classifique pelo nome com a tabela acima. Nome que não encaixa em nenhuma coluna: trate como secreta até provar o contrário.
3. Confira o lugar 2, nome por nome. Abra o painel e compare com a lista:
- Netlify: Project configuration → Environment variables. Cada variável tem valor por contexto (Production, Deploy Previews, Branch deploys, Local development). O que está no ar é Production.
- Vercel: Settings → Environment Variables, marque Production. Pra chave secreta, ligue Sensitive: a documentação (atualizada em 28/08/2026) diz que o valor fica "ilegível depois de criado". Nem você lê de volta. É o que você quer.
- Lovable: as secretas em Cloud → Secrets; as
VITE_no.env.
Nome que está na lista e não está no painel é a sua tela branca.
4. Procure segredo no código. No GitHub, dentro do repositório, busque cada padrão da coluna "secreta": sk_live_, sb_secret_, service_role, BEGIN. Depois abra o .env da raiz: só pode ter linha VITE_. Achou chave secreta? Troque a chave no serviço de origem (Stripe, Supabase) antes de apagar a linha. Trocar invalida a que vazou; apagar só esconde.
5. Confira o .gitignore, o arquivo que lista o que o git deve ignorar. Precisa ter a linha .env.local ou .env*.local. Se não tiver, peça pra IA acrescentar.
6. Republique. Qualquer mudança nos passos 3 a 5 só vale depois de um deploy novo. Janela anônima pra conferir.
Sobre a rede de proteção que você acha que tem: o GitHub bloqueia envio de segredo sozinho só em repositório público (por padrão desde fevereiro de 2024). O seu, do Lovable, nasce privado, e pra privado isso é produto pago. O passo 4 é você.
O que isso era, na parede inteira
Variável de ambiente é um item da fase Construa: o app roda onde você manda, com a chave certa em cada lugar. O item seguinte é o que este post deixou de fora de propósito: teste e produção separados, quando cada variável passa a ter dois valores, um pro banco de teste e outro pro de verdade. A ordem em que isso é feito importa. Por hoje, os três lugares conferidos já tiram você da tela branca.
Fontes
- Simpliia, blog BR de correção de apps Lovable (a fala do início; relato de quem conserta, não estatística): https://simpliia.com.br/blog/erros-comuns-lovable/
- The Twelve-Factor App, fator III, Config (Adam Wiggins, Heroku, 2011): https://12factor.net/config
- Vite, Env Variables and Modes (arquivos
.env,.env.localfora do git, prefixoVITE_): https://vite.dev/guide/env-and-mode - Netlify, Get started with environment variables (caminho no painel, contextos, "changes require a build and deploy"): https://docs.netlify.com/build/environment-variables/get-started/
- Vercel, Sensitive environment variables (atualizado em 28/08/2026): https://vercel.com/docs/environment-variables/sensitive-environment-variables
- Supabase, API keys (
sb_publishable_,sb_secret_, fim das chavesanon/service_roleaté o fim de 2026): https://supabase.com/docs/guides/getting-started/api-keys - Stripe, Best practices for managing secret API keys (buscar
sk_live_; tratar exposição como comprometimento): https://docs.stripe.com/keys-best-practices - GitHub Changelog, 29/02/2024, push protection ligada por padrão pra contas gratuitas em repositório público: https://github.blog/changelog/2024-02-29-push-protection-is-enabled-for-free-users-on-github/
- GitHub Docs, Push protection (privado exige GitHub Secret Protection): https://docs.github.com/en/code-security/concepts/secret-security/push-protection