Aquí FormData supera a v-model
No necesitas reactividad por pulsación. Leer al enviar evita refs y lógica de reinicio y conserva required nativo.
integraciones · framework
Un contacto de tres campos no necesita estado continuo ni una ruta Express o serverless solo para reenviar texto a una API.
Dirígelo a mailcontact sin JavaScript o usa @submit.prevent y FormData para permanecer en la página. Sin servidor en tu proyecto.
configuración recomendada
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.
<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
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.
<script setup>
import { ref } from "vue";
const sent = ref(false);
const sending = ref(false);
async function submit(event) {
sending.value = true;
await fetch("https://mailcontact.app/api/forms/your-form-id", {
method: "POST",
body: new FormData(event.target),
});
sending.value = false;
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 :disabled="sending">{{ sending ? "Sending..." : "Send" }}</button>
</form>
</template>cómo funciona
Una bandeja por proyecto con endpoint y email antes del primer componente.
Pega y cambia ID. new FormData(event.target) recoge los atributos name sin v-model ni objetos reactivos sincronizados.
Añade Discord, Slack, email o webhook para recibir donde ya estás, sin revisar bases de datos.
por qué mailcontact
No necesitas reactividad por pulsación. Leer al enviar evita refs y lógica de reinicio y conserva required nativo.
Sin SSR, Nitro ni adaptadores. El mismo código en Vite, Vue CLI o islas: solo depende de fetch.
Hacerlo tú exige decidir dónde guardar y crear una pantalla. La bandeja ya existe y también recibe en [email protected].
preguntas frecuentes
No por sí solo. El navegador no habla SMTP y una clave API en Vue queda expuesta. Debe enviarse a algún servidor; solo eliges si quieres mantenerlo tú. Con un endpoint no es necesario.
No. Quita el script y dirige action al endpoint: funciona sin JavaScript, ideal para páginas estáticas. Utiliza @submit.prevent para permanecer en la página y mostrar tu resultado.
Conserva la validación del navegador. required, type="email" y pattern siguen aplicándose porque es un formulario real. Para mensajes personalizados, comprueba event.target.checkValidity() antes del fetch y muestra los textos que quieras.
Sí. No depende de script setup ni Composition API: usa fetch y FormData. Mueve submit a methods y sent a data para Options API, incluido Vue 2.
relacionado
Formularios y una dirección de email real, juntos, con avisos en tus herramientas. Empieza con una cuenta gratuita.
Crear formulario gratisSin tarjeta de crédito. Free incluye un proyecto y 50 mensajes de formulario al mes.