// API, Resend, Zod e rate limit
Como este projeto implementa o formulário de contato: validação com Zod, rate limit, reCAPTCHA e envio com Resend. Exemplos de código para replicar no seu projeto.
// stack do formulário de contato
O formulário envia os dados para uma API route em Next.js. A rota valida o payload com Zod, aplica rate limit por IP, opcionalmente reCAPTCHA e envia o e-mail via Resend. Mensagens de erro vêm das traduções (i18n).
Resend (envio), Zod (validação), rate limit em memória ou Redis, reCAPTCHA v3. Código em src/app/api/contact e src/features/home/contact.
import { z } from "zod";const contactSchema = z.object({name: z.string().min(2).max(100),email: z.string().email(),message: z.string().min(10).max(2000),recaptchaToken: z.string().nullable().optional(),});type ContactPayload = z.infer<typeof contactSchema>;
// do formulário até o e-mail
O usuário preenche nome, e-mail e mensagem no cliente. O front envia POST para /api/contact. A API valida com Zod, verifica rate limit e reCAPTCHA (se configurado), e chama o Resend para enviar o e-mail.
Em erro (validação, rate limit ou falha no envio), a API devolve mensagem clara; o front exibe sem expor detalhes internos. Labels e mensagens vêm das traduções (a11y e i18n).
// In the form componentconst res = await fetch("/api/contact", {method: "POST",headers: { "Content-Type": "application/json" },body: JSON.stringify({name: formData.name,email: formData.email,message: formData.message,}),});if (!res.ok) {const data = await res.json();setError(data.error ?? "Send failed");return;}// Success: show message and clear form
// Resend, Nodemailer, React Email
Algumas opções para enviar e-mail na API do Next: Resend (usado neste projeto), Nodemailer (SMTP direto), React Email (templates em React). Abaixo, como implementar na API route com Resend e com Nodemailer.
Libs que você pode usar:
// app/api/contact/route.tsimport { Resend } from "resend";export async function POST(request: Request) {const { name, email, message } = await request.json();// In production: validate body with Zod (see API section above)const resend = new Resend(process.env.RESEND_API_KEY);const { error } = await resend.emails.send({from: "onboarding@resend.dev",to: "you@example.com",subject: `Contato: ${name}`,replyTo: email,text: message,});if (error) return Response.json({ error: error.message }, { status: 503 });return Response.json({ ok: true });}
// app/api/contact/route.tsimport nodemailer from "nodemailer";export async function POST(request: Request) {const { name, email, message } = await request.json();// In production: validate body with Zod firstconst transport = nodemailer.createTransport({host: process.env.SMTP_HOST,port: Number(process.env.SMTP_PORT),secure: true,auth: {user: process.env.SMTP_USER,pass: process.env.SMTP_PASS,},});try {await transport.sendMail({from: process.env.SMTP_FROM,to: "you@example.com",replyTo: email,subject: `Contato: ${name}`,text: message,});return Response.json({ ok: true });} catch (err) {return Response.json({ error: "Send failed" }, { status: 503 });}}
// POST /api/contact
A rota lê o body, valida com o schema Zod, aplica rate limit por IP e, se ok, chama o Resend com a chave em variável de ambiente. Nunca exponha RESEND_API_KEY no cliente.
Para replicar: crie a API route, defina o schema Zod, use rate limit (middleware ou lib) e configure RESEND_API_KEY no .env. Mensagens de sucesso e erro via traduções (i18n e a11y).
// app/api/contact/route.tsimport { Resend } from "resend";import { contactSchema } from "@/lib/schemas/contact";export async function POST(request: Request) {const body = await request.json();const parsed = contactSchema.safeParse(body);if (!parsed.success) {return Response.json({ error: "Invalid data" },{ status: 400 });}const resend = new Resend(process.env.RESEND_API_KEY);const { error } = await resend.emails.send({from: "you@yourdomain.com",to: "dest@example.com",subject: `Contact: ${parsed.data.name}`,text: parsed.data.message,});if (error) {return Response.json({ error: "Send failed" }, { status: 503 });}return Response.json({ ok: true });}
i18n, SEO, AI Chatbot, Analytics e Testing: todas com código aberto e documentação no repositório.