JavaScript envia e-mail a partir de um servidor, nunca diretamente do navegador. Não há como o código do lado do cliente abrir uma conexão SMTP, e colocar credenciais de e-mail em uma página as entregaria a qualquer pessoa que abrisse as ferramentas de desenvolvedor. A verdadeira questão é qual caminho usar no lado do servidor: SMTP por meio de uma biblioteca como o Nodemailer, ou uma requisição HTTP a uma API de e-mail. Este artigo mostra os dois.
Por que o navegador não consegue enviar e-mail?
O envio de e-mail funciona sobre SMTP, um protocolo TCP. Os navegadores não expõem sockets TCP brutos ao JavaScript, então não há como se comunicar com um servidor de e-mail pelo lado do cliente. Mesmo que houvesse, as credenciais SMTP ou a chave API ficariam em código que qualquer pessoa pode ler. O navegador coleta os dados do formulário e os envia ao seu backend; o backend envia o e-mail. Essa separação é todo o padrão.
Como enviar a partir de um backend Node com SMTP?
O Nodemailer é a biblioteca padrão para SMTP no Node. Você configura um transporte uma vez e depois chama sendMail:
import nodemailer from "nodemailer";
const transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 587,
secure: false,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
await transporter.sendMail({
from: "you@yourdomain.com",
to: "recipient@example.org",
subject: "Your receipt",
text: "Thanks for your order.",
html: "<p>Thanks for your order.</p>",
});
Isso funciona bem em um servidor de longa execução. O passo a passo completo, incluindo anexos e testes locais, está em enviando e-mails com Nodemailer.
Como enviar com uma API de e-mail via HTTP?
O outro caminho é uma requisição HTTP. Seu backend chama uma API de e-mail com fetch, o que evita operar um servidor de e-mail e funciona da mesma forma em um host tradicional ou em uma função serverless:
const res = await fetch("https://api.bird.com/v1/emails", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BIRD_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "you@yourdomain.com",
to: "delivered@bird.dev",
subject: "Hello from JavaScript",
html: "<p>It works.</p>",
}),
});
if (!res.ok) {
throw new Error(`Send failed: ${res.status}`);
}
A chave continua no servidor, em uma variável de ambiente, nunca enviada ao cliente.
Envie com Bird
O Bird Node SDK encapsula essa mesma chamada HTTP, então você pula o fetch manual e obtém resultados tipados:
import { BirdClient } from "@messagebird/sdk";
const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });
const { data, error } = await bird.email
.send({
from: "you@yourdomain.com",
to: ["delivered@bird.dev"],
subject: "Hello from Node",
html: "<p>It works.</p>",
})
.safe();
O endereço sandbox do delivered@bird.dev sempre aceita e-mails, então a primeira execução confirma sua configuração. Se você cria os corpos dos e-mails como componentes React, combine com o React Email, que renderiza o componente para o HTML que você passa em html.
Perguntas frequentes
JavaScript do lado do cliente consegue enviar e-mail?
Não. Os navegadores não conseguem abrir conexões SMTP, e qualquer credencial em código do cliente fica exposta. O navegador envia os dados do formulário ao seu backend, e o backend envia o e-mail.
Devo usar Nodemailer ou uma API via HTTP?
O Nodemailer é uma boa escolha em um servidor de longa execução onde você controla SMTP. Uma HTTP API é mais simples quando você quer evitar operar um servidor de e-mail e é a opção confiável em plataformas serverless onde sockets SMTP não estão disponíveis.
Onde guardo a chave API?
Em uma variável de ambiente no lado do servidor, lida em tempo de execução. Ela nunca deve aparecer em código front-end ou em um repositório público.
JavaScript sozinho não entrega e-mail; um servidor faz isso. Para aprofundar no caminho API, a visão geral do produto de e-mail e o guia de envio de e-mail cobrem os detalhes.