Vanilla JavaScript (@frontmail/browser)
@frontmail/browser es un SDK diminuto (< 3,5 kB con gzip) y sin dependencias para cualquier sitio
web. Su API imita la de @emailjs/browser, así que el código existente necesita pocos cambios.
Instalación
Sección titulada «Instalación»npm install @frontmail/browserimport { init, send, sendForm, getStatus } from '@frontmail/browser';<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_4f2a…' });</script>El build UMD expone un objeto global frontmail con init, send, sendForm, getStatus y las
clases de error. Carga siempre una versión exacta con Subresource Integrity: consulta
Fija la versión más abajo.
init(options)
Sección titulada «init(options)»Llámalo una vez, antes de enviar:
init({ publicKey: 'pk_4f2a…', blockHeadless: true, // opcional, consulta Protección contra bots blockList: { list: ['spam@example.net'], watchVariable: 'email' }, limitRate: { id: 'contact', throttle: 10_000 }, // como máximo un envío cada 10 s retry: { retries: 3, baseDelayMs: 300 }, // por defecto; `false` desactiva los reintentos timeoutMs: 15_000, // por intento apiUrl: 'https://api.frontmail.dev', // por defecto});También funciona init('pk_4f2a…') solo con la cadena de la clave.
send(serviceId, templateId, params?, options?)
Sección titulada «send(serviceId, templateId, params?, options?)»const result = await send('svc_01J9…', 'tpl_order', { name: 'Jana', items: [{ title: 'Habitación', qty: 2, price: 89 }],});// { messageId: 'msg_…', status: 'queued' | 'held', statusToken: '…', status_code: 202, text: 'OK' }serviceIdpuede sernullpara usar el servicio por defecto de la organización.paramsse validan en el servidor contra el esquema de la plantilla.optionsaceptaturnstileToken,attachments,idempotencyKey,locale,signal(AbortSignal),publicKeypor llamada y protecciones por llamada (blockHeadless,blockList,limitRate). Una cadena simple se trata como la clave pública, igual que en EmailJS.locale(p. ej.'de') elige un idioma de la plantilla; un idioma desconocido recurre al mismo idioma base y, si no, al idioma predeterminado.result.localees el idioma en que se envió el correo.
La promesa se resuelve tanto con queued como con held: un mensaje retenido se ha aceptado y
se enviará cuando haya créditos disponibles (consulta
Cola de correos retenidos). En los demás casos se rechaza con un
error tipado (consulta Gestión de errores).
sendForm(serviceId, templateId, form, options?)
Sección titulada «sendForm(serviceId, templateId, form, options?)»<form id="contact"> <input name="name" required> <input name="email" type="email" required> <textarea name="message"></textarea> <input type="file" name="attachment"> <div class="cf-turnstile" data-sitekey="YOUR_TURNSTILE_SITE_KEY"></div> <button>Enviar</button></form><script type="module"> import { init, sendForm } from '@frontmail/browser'; init({ publicKey: 'pk_4f2a…' });
document.getElementById('contact').addEventListener('submit', async (event) => { event.preventDefault(); const { status } = await sendForm('svc_01J9…', 'tpl_contact', event.target); // o bien: sendForm('svc_01J9…', 'tpl_contact', '#contact') });</script>El formulario se envía como multipart/form-data. Los campos de texto se convierten en parámetros
(convertidos a los tipos declarados), los
campos de archivo se convierten en adjuntos y el token de Turnstile de cf-turnstile-response se
recoge automáticamente. Usa la site key de tu propio widget de Turnstile: consulta
Cloudflare Turnstile.
Los campos que no deben salir de tu sitio se omiten: los campos de contraseña
(type="password"), los campos anti-CSRF de los frameworks habituales (csrfmiddlewaretoken,
_token, authenticity_token, __RequestVerificationToken, _csrf, csrf_token) y los nombres
reservados de la API (accessToken, privateKey, turnstile_key, …). Elige tú los campos con
formFields:
await sendForm('svc_01J9…', 'tpl_contact', '#contact', { formFields: { include: ['name', 'email', 'message'] }, // solo estos (+ token de Turnstile) // o bien: formFields: { exclude: ['internal_note'] }});Para enviar el formulario en un idioma de la plantilla, pasa
{ locale: 'de' } – se envía como el campo reservado fm_locale – o añade tú mismo un campo
fm_locale al formulario (p. ej. un <select name="fm_locale"> de idiomas); el campo del formulario
tiene prioridad. Un campo llamado locale sigue siendo un parámetro normal de la plantilla.
getStatus(messageId, options)
Sección titulada «getStatus(messageId, options)»const status = await getStatus(result.messageId, { token: result.statusToken });// { messageId, status: 'sent', createdAt, sentAt, templateId, serviceId, events: [...] }Con una clave pública solo puedes leer los mensajes que has enviado tú, usando el statusToken del
resultado del envío. El SDK lo envía en la cabecera X-Frontmail-Status-Token (no en la URL, para
que no acabe en los registros). Consulta Estados de los mensajes.
Fija la versión y usa Subresource Integrity
Sección titulada «Fija la versión y usa Subresource Integrity»Una etiqueta <script> se ejecuta con acceso completo a tu página. Carga una versión exacta y deja
que el navegador verifique su hash, para que un archivo modificado (una CDN o una versión
comprometida) se rechace en lugar de ejecutarse:
<script src="https://cdn.jsdelivr.net/npm/@frontmail/browser@0.1.0/dist/frontmail.umd.js" integrity="sha384-g2Rxznkz2yb/YYSdVTkXLxZFZ2Nh2+XdhPStxh0stydXFF3gYjDuyHimWIZLJDCc" crossorigin="anonymous"></script>- jsDelivr (npm): el hash de cada versión está en sus notas de la versión en GitHub (y en el botón «Copy HTML + SRI» de jsDelivr).
- CDN de Frontmail:
https://cdn.frontmail.dev/v<versión>/frontmail.umd.js; su valor deintegrityestá enhttps://cdn.frontmail.dev/v<versión>/sri.json. - Para actualizar, cambia la versión y el hash a la vez (consulta el registro de cambios).
Content Security Policy
Sección titulada «Content Security Policy»Si tu sitio usa CSP, permite:
connect-src https://api.frontmail.dev;script-src https://cdn.jsdelivr.net https://challenges.cloudflare.com; # build de la CDN (o cdn.frontmail.dev), Turnstileframe-src https://challenges.cloudflare.com; # Turnstile