É muito comum em projetos de software web que existam configurações para que a aplicação funcione como a porta HTTP, chaves de API e outras. Mais comum ainda é que tais configurações possuam divergências entre os ambientes de desenvolvimento, testes e produção. Por causa disso, tais configurações não devem ser escritas diretamente no código das aplicações, o que chamamos de “hard code”, mas sim definidas em variáveis/configurações de ambiente.
Estas variáveis de ambiente podem ser configuradas diretamente no PATH do SO com comandos como SET, o que é bem comum em ambientes produtivos, mas também podem ser utilizados arquivos .env para isso, principalmente em ambientes de desenvolvimento.
No tutorial de hoje eu vou lhe ensinar como configurar o seu projeto Next.js para usar variáveis de ambiente, tanto no client side quanto no server side e as implicações de cada abordagem. Obviamente parto do pressuposto que você já sabe o básico de Next.js, mas se não souber, comece por este outro tutorial aqui.
Vamos lá!
#1 – Setup do Projeto
Vamos começar criando um novo projeto Next.js, com o comando abaixo.
1 2 3 |
npx create-next-app nextjs-dotenv |
O CLI vai lhe fazer algumas perguntas, sendo que nenhuma realmente importa para este tutorial, então pode avançar com os valores padrões ou com o que você preferir.
O próximo passo é criar seu arquivo .env.local na raiz do projeto, sendo esse o nome convencionado e que será procurado pelo Next automaticamente no start do servidor dele. Dentro desse arquivo você coloca as configurações que você precisa e que variam enormemente de projeto para projeto. Abaixo, coloco apenas dois exemplos que já usei e que são comuns.
1 2 3 4 |
API_URL=http://xpto.com/api API_KEY=abc123 |
Também é comum que a gente crie um arquivo .env.example onde você documente as variáveis de ambiente para ajudar os outros devs do projeto a entenderem para quê elas servem e como devem ser configuradas. Abaixo um exemplo bobo, apenas para ilustrar:
1 2 3 4 5 6 7 |
# The API URL API_URL= # The API Key API_KEY= |
Recomendo que inclua o arquivo .env.local no arquivo .gitignore da sua aplicação, que deve ficar na raiz do projeto, se ainda não existir.
1 2 3 |
.env.local |
E com isso temos tudo configurado para o tutorial.
#2 – Usando as Configurações
Se você subir seu projeto agora, vai reparar inclusive que o arquivo das variáveis de ambiente consta como carregado.
Só que no Next.js tem um detalhe importante que é o fato de que, por padrão e por segurança, as variáveis de ambiente somente são carregadas no server side da aplicação, não ficando disponíveis no client side, ou seja, páginas com a diretiva “use client” ou ainda children components dessas páginas.
Assim, se você precisar usar essas variáveis de ambiente no lado do cliente, você tem duas opções. A primeira é através da convenção de nomes, onde se uma variável for nomeada com o prefixo NEXT_PUBLIC_ antes do nome da variável, ela vai automaticamente ser carregada no client-side também, como abaixo.
1 2 3 |
NEXT_PUBLIC_API_URL=http://xpto.com/api |
Assim, nos seus arquivos JSX/TSX que for usar essa variável, basta chamá-la como abaixo (exemplo).
1 2 3 4 |
fetch(process.env.NEXT_PUBLIC_API_URL) .then(data => console.log(data)) |
A outra opção, caso você ache feia essa convenção, é mapear as variáveis de ambiente que você deseja acessar no client-side através do arquivo next.config.js, como abaixo.
1 2 3 4 5 6 7 8 9 10 |
/** @type {import('next').NextConfig} */ const nextConfig = { env: { API_URL: process.env.API_URL } } module.exports = nextConfig |
Basta que você mapeie, inclusive podendo renomear as variáveis depois de mapeadas, cada uma das variáveis que você deseja expor no browser do cliente e ela estará lá, pronta para ser usada após o build do projeto. Abaixo o mesmo exemplo de antes, em uma página “use client”, mas agora após o mapeamento.
1 2 3 4 |
fetch(process.env.API_URL) .then(data => console.log(data)) |
Um ponto muito importante aqui é que você não deve mapear TODAS as variáveis de ambiente sempre, mas somente aquelas que você deseja expor no client side. Isso porque se você mapear (ou colocar o prefixo NEXT_PUBLIC_) em uma variável sensível, como uma senha ou chave de API, ela estará disponível a qualquer um utilizar, mesmo que não seja você, pois em tempo de compilação elas serão injetadas no JS client-side e consequentemente estarão no browser dos usuários para inspeção.
Mas Luiz, e se eu precisar usar variáveis de ambiente “sensíveis” no client side, por causa de uma chamada de API, por exemplo?
Neste caso você deve fazer com que sua página/componente client-side chame o server side de alguma forma, como por exemplo através de Route Handlers. Assim o seu client-side vai chamar o seu server-side e ele vai ter acesso às variáveis “secretas” sem expô-las no browser. Em outro tutorial quero falar a respeito de Route Handlers, mas por enquanto, segue um código exemplo, que deve ser colocado em src/app/api/route.ts (crie este arquivo):
1 2 3 4 5 6 7 8 9 10 11 12 13 |
export async function GET() { const res = await fetch('https://data.mongodb-api.com/...', { headers: { 'Content-Type': 'application/json', 'API-Key': process.env.API_KEY, }, }) const data = await res.json() return Response.json({ data }) } |
Note que acima estou usando a variável de ambiente API_KEY que não foi mapeada no next.config.js e que não possui o prefixo de variável pública. Desta forma ela não está exposta no frontend/client-side, somente no server side e todo Route Handler roda no server side. E para chamar este Route Handler, você faz um fetch normalmente, como abaixo.
1 2 3 4 |
fetch("/api") .then(data => console.log(data)) |
E com isso finalizo mais este tutorial, espero que você tenha gostado.
Até a próxima!
Olá, tudo bem?
O que você achou deste conteúdo? Conte nos comentários.
Obrigado.