integraciones · framework

Un formulario de Nuxt que sobrevive a nuxt generate.

server/api/ con Nitro facilita recibir, hasta que nuxt generate lo convierte en estático: no hay entorno donde ejecutar server/api/contact.post.ts.

Si elegiste Nuxt para exportar estático, usa un endpoint. Funciona igual con nuxt build en Node, nuxt generate en CDN y cualquier preset futuro.

configuración recomendada

Utiliza el script de MailContact con tu diseño.

Añade este HTML a tu sitio o utiliza el generador de formularios. Sustituye el enlace por el de tu formulario. El script alojado inserta la comprobación oculta, gestiona el envío y la verificación automática y conserva el borrador si hay errores. Tú controlas el HTML y el CSS. Los formularios Free muestran un enlace visible «Processed by mailcontact.app»; Pro y Plus no. Los avisos siguen el idioma del navegador; configura data-mailcontact-language="fr" en el formulario para forzar el francés.

contact.html
<form action="https://mailcontact.app/api/forms/your-form-id" method="POST" data-mailcontact-form lang="es" data-mailcontact-language="es">
  <input type="hidden" name="_language" value="es" />
  <fieldset>
    <legend>Contáctanos</legend>
    <label>
      Nombre (opcional)
      <input name="name" type="text" autocomplete="name" maxlength="200" />
    </label>
    <label>
      Correo electrónico
      <input name="email" type="email" autocomplete="email" maxlength="320" required />
    </label>
    <label>
      Mensaje
      <textarea name="message" rows="5" maxlength="5000" required></textarea>
    </label>
    <noscript>
    <div aria-hidden="true" style="position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden;">
      <label>Sitio web
        <input name="company_website" type="text" tabindex="-1" autocomplete="off" />
      </label>
    </div>
    </noscript>
    <button type="submit">Enviar mensaje</button>
  </fieldset>
  <p data-contact-status role="status" aria-live="polite" aria-atomic="true"></p>
</form>
<script defer src="https://mailcontact.app/forms/v1.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Para un componente con su propio controlador de envío, carga el mismo script y utiliza MailContact.prepare(form) y MailContact.send() en lugar del marcador automático. Consulta la referencia de interfaces personalizadas para carga, avisos y atribución de Free.

el código

Alternativa: una integración directa para Nuxt.

Este ejemplo envía directamente a la API. Mantén el campo obligatorio company_website presente y vacío. Los envíos nativos abren JSON si tienen éxito o una página de verificación si hace falta. Los scripts sin verificación envían los mensajes sospechosos a Spam; el spam claro también se retiene sin alertas ni consumo de cuota. Una respuesta de éxito confirma recepción, incluida revisión, o el descarte silencioso de una trampa rellenada. Consulta protección contra spam para conocer todo el funcionamiento.

pages/contact.vue
<script setup>
// No server/api/contact.post.ts. Nothing here needs Nitro at runtime,
// so `nuxt generate` keeps this page fully working.
const sent = ref(false);

async function submit(event) {
  await $fetch("https://mailcontact.app/api/forms/your-form-id", {
    method: "POST",
    body: new FormData(event.target),
  });
  sent.value = true;
}
</script>

<template>
  <p v-if="sent">Thanks. We'll be in touch.</p>

  <form v-else @submit.prevent="submit">
    <input name="name" placeholder="Your name" required />
    <input name="email" type="email" placeholder="[email protected]" required />
    <textarea name="message" placeholder="What's on your mind?" required />
    <input name="company_website" type="text" tabindex="-1" autocomplete="off"
      style="position:absolute;left:-10000px" aria-hidden="true" />

    <button>Send</button>
  </form>
</template>

cómo funciona

Tres pasos de principio a fin.

01

Crear una bandeja

Una bandeja por proyecto con endpoint y email activos antes de añadir la página.

02

Añade la página

Pega en pages/contact.vue y sustituye ID. Sin server/, runtimeConfig ni claves privadas en el cliente.

03

Recibe avisos

Añade Discord, Slack, email o webhook y recibe avisos al instante.

por qué mailcontact

Pensado para funcionar con Nuxt.

La salida estática sigue siendo posible

Una ruta Nitro impide que baste nuxt generate. Un formulario externo mantiene la opción de publicar todo como archivos.

Sin clave de correo en runtimeConfig

La versión propia exige clave de email, almacenamiento y ajustes por proveedor. Aquí no hay clave que filtrar o renovar.

El preset deja de importar

Los presets Nitro cambian por alojamiento. Una URL externa funciona igual sin tocarlos.

preguntas frecuentes

Nuxt + mailcontact: tus preguntas resueltas

¿Puedo utilizar una ruta de servidor de Nuxt?

Sí, si despliegas servidor. server/api/contact.post.ts funciona con nuxt build en Node o serverless. Deja de funcionar con nuxt generate, sin Nitro para recibir. Si quieres estático, mantén fuera el formulario.

¿Funciona con Nuxt 3 y Nuxt 4?

Sí. ref, $fetch y @submit.prevent son estables en ambas versiones. Puedes sustituir $fetch por fetch: envías FormData y no dependes de la capa de Nuxt.

¿Debo usar useFetch aquí?

No. useFetch sirve para datos durante el renderizado y deduplica y almacena en caché, algo inadecuado para un POST de un clic. Llama directamente a $fetch o fetch en el controlador.

¿Cómo evito el spam sin captcha?

company_website debe existir y estar vacío. Rellenarlo descarta sin avisar, pero un bot puede omitirlo. MailContact añade límites y controles de contenido y campañas. El script verifica automáticamente si hace falta; el spam claro se retiene sin alertas ni cuota.

relacionado

También funciona con

Una bandeja por cada proyecto de Nuxt que publiques.

Formularios y una dirección de email real, juntos, con avisos en tus herramientas. Empieza con una cuenta gratuita.

Crear formulario gratis

Sin tarjeta de crédito. Free incluye un proyecto y 50 mensajes de formulario al mes.