Formulario de contacto PRO: correos, base de datos y anti-spam en Next.js
Tu web ya luce genial y muestra posts desde MongoDB. Falta el punto clave: que los visitantes puedan escribirte y que NINGÚN mensaje se pierda en el limbo.
Tu web ya luce genial y muestra posts desde MongoDB. Falta el punto clave: que los visitantes puedan escribirte y que NINGÚN mensaje se pierda en el limbo.
En este artículo vamos a construir un sistema de contacto robusto que combine tres capas de seguridad: validación en cliente, validación en servidor y protección anti-spam.
¿Por qué necesitas las tres capas? La validación en cliente mejora la experiencia de usuario con feedback instantáneo. La validación en servidor garantiza la integridad de los datos aunque alguien intente saltarse el frontend. Y la protección anti-spam evita que tu bandeja de entrada se llene de basura.
Paso 1: Estructura del formulario con React Hook Form. Usaremos React Hook Form por su rendimiento y facilidad de uso. Instalamos las dependencias:
$ npm install react-hook-form @hookform/resolvers zod
Zod nos permitirá definir esquemas de validación type-safe.
Paso 2: Crear la API Route en Next.js. En el App Router, creamos app/api/contact/route.ts. Esta ruta recibirá los datos del formulario, los validará de nuevo en servidor, los guardará en MongoDB y enviará el correo con Nodemailer.
// app/api/contact/route.ts
import { NextResponse } from 'next/server';
import { z } from 'zod';
const contactSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
message: z.string().min(10),
honeypot: z.string().max(0) // Anti-spam
});
export async function POST(req: Request) {
const body = await req.json();
const result = contactSchema.safeParse(body);
if (!result.success) {
return NextResponse.json({ error: 'Datos inválidos' }, { status: 400 });
}
// Guardar en MongoDB y enviar email...
return NextResponse.json({ success: true });
}
Paso 3: Configurar Nodemailer. Para el envío de correos necesitarás configurar un servicio SMTP. Puedes usar Gmail (para desarrollo), SendGrid, Mailgun o Amazon SES para producción. Las credenciales van en variables de entorno.
Paso 4: Honeypot anti-spam. La técnica del honeypot consiste en añadir un campo oculto que los usuarios reales nunca rellenan pero los bots sí. Si ese campo tiene valor, rechazamos la petición silenciosamente.
Paso 5: Rate limiting. Implementamos un límite de peticiones por IP usando una librería como rate-limiter-flexible o simplemente un Map en memoria para proyectos pequeños. Esto evita ataques de fuerza bruta.
Bonus: Feedback visual. Añadimos estados de loading, success y error con animaciones suaves usando Framer Motion. El usuario debe saber en todo momento qué está pasando.
Con este sistema tienes un formulario de contacto profesional que no pierde ningún mensaje, protege tu web de spam y ofrece una experiencia de usuario impecable.