SOP: conectar formularios de contacto con Orbitype, Vercel y SendGrid
Guía para enviar notificaciones fiables desde formularios Nuxt en Vercel con SendGrid y guardar cada contacto de forma opcional en Orbitype.
Conectar un formulario de contacto en Nuxt con SendGrid y Orbitype tiene una regla simple: el navegador solo envía los datos al servidor; el servidor valida, avisa por correo y, si está habilitado, guarda el registro. Así los secretos no se exponen y un fallo opcional de almacenamiento no impide que el equipo reciba el contacto.
Este SOP aplica a sitios Nuxt 3 con Orbitype headless desplegados en Vercel. El resultado esperado es una ruta POST /api/contacts que notifica a SENDGRID_TO_EMAIL y puede insertar el envío en una tabla contacts.
Respuesta corta: arquitectura recomendada
Persona usuaria
→ formulario del sitio
→ POST /api/contacts en Nuxt/Vercel
→ SendGrid Mail Send → bandeja de leads
→ Orbitype SQL (opcional) → tabla contacts
La ruta de servidor es el único lugar que conoce SENDGRID_API_KEY y la clave SQL de Orbitype. Configura Reply-To con el correo del formulario; no uses ese correo como remitente porque SendGrid exige un remitente verificado.
Qué necesitas antes de empezar
- Un formulario que envíe JSON a
POST /api/contacts. - Una cuenta de SendGrid con una API key con permiso Mail Send.
- Un remitente o dominio ya verificado en SendGrid.
- Variables de entorno en local y en Vercel.
- Acceso al SQL de Orbitype solo si se guardarán los contactos.
Si el formulario ya envía mensajes a una lista de correo, conserva el mismo principio de integración server-side explicado en este procedimiento para formularios y email: ninguna clave privada debe formar parte del JavaScript descargado por quien visita el sitio.
1. Configura SendGrid correctamente
Crea una API key en Settings → API Keys con el permiso mínimo de Mail Send. Después verifica el correo o, preferiblemente, el dominio que usarás como SENDGRID_FROM_EMAIL en Settings → Sender Authentication.
Estas son las variables que necesita la ruta:
| Variable | Uso |
|---|---|
SENDGRID_API_KEY | Autoriza el envío con Mail Send. |
SENDGRID_FROM_EMAIL | Remitente verificado por SendGrid. |
SENDGRID_FROM_NAME | Nombre que verá quien recibe el aviso. |
SENDGRID_TO_EMAIL | Buzón que recibe los nuevos leads. |
Un error 403 o un mensaje sobre un remitente no verificado casi siempre significa que SENDGRID_FROM_EMAIL no tiene una identidad válida. Mientras se verifica el dominio del cliente, usa temporalmente una dirección que ya esté aprobada dentro de la misma cuenta de SendGrid.
2. Añade Orbitype solo como almacenamiento opcional
El correo es el resultado crítico: evita perder un lead. Orbitype complementa ese flujo con una copia consultable del envío, pero su indisponibilidad no debe convertir un envío válido en un error para la persona usuaria.
La integración SQL necesita estas variables:
ORBITYPE_MOCK=false
ORBITYPE_API_SQL_URL="https://core.orbitype.com/api/sql/v1"
ORBITYPE_API_SQL_KEY="tu-clave-sql-de-orbitype"
Si aún no existe, crea una tabla compatible con el payload real del formulario:
CREATE TABLE IF NOT EXISTS contacts (
id varchar(255) DEFAULT uid() PRIMARY KEY,
first_name text DEFAULT ''::text,
last_name text DEFAULT ''::text,
email text DEFAULT ''::text,
phone text DEFAULT ''::text,
interest text DEFAULT ''::text,
learner_type text DEFAULT ''::text,
message text DEFAULT ''::text,
created_at timestamptz DEFAULT CURRENT_TIMESTAMP
);
Mantén alineados los nombres del formulario, la validación de la API y las columnas de la tabla. Si cambias interest por otro campo, actualiza los tres puntos en el mismo cambio.
3. Declara el mismo contrato de entorno en local y producción
En .env local utiliza valores reales únicamente en tu entorno de trabajo; el archivo no debe versionarse. En .env.example deja los nombres y valores de ejemplo, nunca secretos:
# SendGrid
SENDGRID_API_KEY="SG...."
SENDGRID_FROM_EMAIL="verified-sender@example.com"
SENDGRID_FROM_NAME="Nombre del sitio"
SENDGRID_TO_EMAIL="leads@example.com"
# Orbitype: opcional si se almacenan contactos
ORBITYPE_MOCK=false
ORBITYPE_API_SQL_URL="https://core.orbitype.com/api/sql/v1"
ORBITYPE_API_SQL_KEY="your-sql-api-key"
En Vercel agrega el mismo conjunto en Settings → Environment Variables para Production y, si el equipo revisa formularios antes de publicar, también para Preview. Después crea un despliegue nuevo: las variables añadidas no cambian los deployments ya generados.
4. Comportamiento que debe tener POST /api/contacts
La ruta debe validar los campos obligatorios antes de llamar a servicios externos. Tras una validación correcta, envía el correo y guarda el contacto si Orbitype está habilitado. Si el correo falla, responde con un error claro y no finjas que el lead fue recibido. Si el correo funciona pero la inserción falla, conserva el éxito y registra el estado de almacenamiento de forma segura.
Una respuesta útil separa los resultados:
{
"ok": true,
"emailed": true,
"stored": false
}
No devuelvas claves, payloads completos ni detalles internos de proveedores al navegador. En los logs del servidor, evita conservar mensajes o datos personales más tiempo del necesario.
5. Prueba el flujo de punta a punta
Primero reinicia el servidor de Nuxt tras cambiar variables. Después envía un registro de prueba controlado contra local:
curl -s -X POST http://127.0.0.1:3000/api/contacts \
-H "Content-Type: application/json" \
-d '{
"first_name": "Test",
"last_name": "User",
"email": "you@example.com",
"phone": "+41 00 000 00 00",
"interest": "example",
"learner_type": "example",
"message": "Connectivity test"
}'
Confirma, en este orden:
- La API responde
ok: trueyemailed: true. - El correo llega al buzón configurado, incluida la opción de responder directamente a quien llenó el formulario.
- Si Orbitype está activado, existe la fila esperada en
contacts. - Tras desplegar en Vercel, repite la prueba desde el formulario público.
Errores frecuentes y su corrección
| Síntoma | Causa habitual | Acción recomendada |
|---|---|---|
403 de SendGrid | Remitente no verificado | Verifica el dominio o usa un FROM ya aprobado. |
400 por campos faltantes | El payload no coincide con la ruta | Revisa nombres, tipos y validación del formulario. |
emailed: true, stored: false | Tabla o clave SQL ausente | Crea contacts y configura las variables de Orbitype. |
| Funciona en local, no en Vercel | Faltan variables o deployment anterior | Configura Production/Preview y redepliega. |
| No llega el correo | Buzón incorrecto, spam o demora | Revisa Spam, SENDGRID_TO_EMAIL y la actividad de SendGrid. |
Checklist de salida
- API key de SendGrid creada con permiso Mail Send.
-
SENDGRID_FROM_EMAILverificado. - Variables
SENDGRID_*disponibles en local y Vercel. - Tabla y clave SQL de Orbitype configuradas, si aplica.
- Validación de campos y
Reply-Toimplementados en la ruta. - Prueba local confirma correo y, si aplica, almacenamiento.
- Producción se redeplegó después de configurar secretos.
- Ningún
.envni API key se incluyó en Git.
La implementación es fiable cuando la persona recibe una confirmación honesta, el equipo recibe el lead y los servicios opcionales no silencian un contacto válido. Mantener ese orden protege tanto la operación como las credenciales.