Ir al contenido

5. Crea el formulario

Ahora la parte que vive en tu web: un formulario HTML normal y unas pocas líneas de JavaScript.

Qué Aspecto Dónde encontrarlo
Clave pública pk_… Seguridad → Clave pública (botón de copiar), o en la pestaña Fragmentos de la plantilla
ID de la plantilla tpl_… Lista de Plantillas, columna ID de la plantilla, o en la pestaña Fragmentos
ID del servicio svc_… En la pestaña Fragmentos, o sáltatelo y pasa null para usar tu servicio predeterminado

Lo más fácil es la pestaña Fragmentos de la plantilla Formulario de contacto. Genera código listo para HTML / JS, React, Vue, Svelte, Node.js y cURL con tu clave, tus ID y todos los parámetros de la plantilla ya rellenados.

La pestaña Fragmentos del editor de plantillas con selectores de framework y código generado que contiene la clave pública, el ID del servicio y el ID de la plantilla

Los fragmentos generados llaman a send() con un objeto de valores. Para un formulario es más sencillo usar sendForm(), que lee los campos directamente del <form>: es lo que hacemos a continuación.

  1. Añade el formulario a tu página. Los atributos name tienen que coincidir con los parámetros de la plantilla: name, email y message son obligatorios; phone y topic, opcionales.

  2. Pon el widget de Turnstile dentro del formulario. Añade un campo oculto cf-turnstile-response que sendForm() envía junto con el resto. Usa la clave de sitio de tu propio widget de Turnstile del paso 4. Si de momento te has saltado la CAPTCHA, no pongas el widget.

  3. Carga el SDK desde la CDN. Crea un objeto global frontmail.

  4. Llama a frontmail.init() con tu clave pública y a frontmail.sendForm() al enviar.

<form id="contact">
<label>Nombre <input name="name" required maxlength="200" /></label>
<label>Correo electrónico <input name="email" type="email" required /></label>
<label>Mensaje <textarea name="message" required></textarea></label>
<!-- Turnstile añade el campo oculto cf-turnstile-response -->
<div class="cf-turnstile" data-sitekey="YOUR_TURNSTILE_SITE_KEY"></div>
<button type="submit">Enviar</button>
<p id="form-status" role="status"></p>
</form>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<script
src="https://cdn.jsdelivr.net/npm/@frontmail/browser@0.1.0/dist/frontmail.umd.js"
integrity="sha384-g2Rxznkz2yb/YYSdVTkXLxZFZ2Nh2+XdhPStxh0stydXFF3gYjDuyHimWIZLJDCc"
crossorigin="anonymous"></script>
<script>
frontmail.init({ publicKey: 'pk_…' });
const form = document.getElementById('contact');
const status = document.getElementById('form-status');
form.addEventListener('submit', async (event) => {
event.preventDefault();
status.textContent = 'Enviando…';
try {
// null = tu servicio predeterminado; o pega el ID svc_… de la pestaña Fragmentos
const result = await frontmail.sendForm(null, 'tpl_…', form);
// result.status es "queued" (en camino) o "held" (aceptado, se envía cuando vuelva a haber créditos)
status.textContent = '¡Gracias! Te responderemos pronto.';
form.reset();
} catch (err) {
status.textContent = 'Lo sentimos, no ha funcionado: ' + err.message;
} finally {
window.turnstile?.reset(); // un token de Turnstile solo vale una vez
}
});
</script>

Qué pasa al enviar:

  • sendForm() envía a Frontmail los campos del formulario, tu clave pública y el token de Turnstile.
  • Frontmail comprueba el origen, la CAPTCHA y los parámetros, y responde enseguida con { messageId, status }. El correo en sí se envía en segundo plano.
  • Tanto queued como held significan éxito: el mensaje se ha aceptado y está a salvo. En ambos casos, muestra al visitante un agradecimiento normal.
  • Si hay un problema, la promesa se rechaza con un error que tiene un code y un message legible, p. ej. invalid_template_params cuando la dirección de correo no es válida o falta un campo obligatorio. Los errores de red y los fallos puntuales del servidor se reintentan automáticamente, sin enviar dos veces.

Los paquetes para frameworks incluyen un componente de formulario listo que renderiza el widget de Turnstile y gestiona por ti el estado del envío: