integraciones · framework

Un formulario para React sin crear servidor.

Una SPA React con Vite no tiene servidor de contacto ni necesita añadirlo. Envía desde el navegador a mailcontact (CORS abierto) y recibe mensajes y avisos de Discord, Slack, email o webhook.

La API directa utiliza formulario, fetch y useState. Sin Express, funciones ni SDK de correo. La salida sigue siendo estática.

Prefer zero JavaScript? A plain <form action="…" method="POST"> posts to the same endpoint. See the FAQ for the trade-off.

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 React.

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.

src/components/ContactForm.tsx
import { useState } from "react";

export default function ContactForm() {
  const [status, setStatus] = useState<"idle" | "sending" | "sent" | "error">("idle");

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const data = new FormData(event.currentTarget);
    setStatus("sending");
    try {
      const res = await fetch("https://mailcontact.app/api/forms/your-form-id", {
        method: "POST",
        body: data,
      });
      setStatus(res.ok ? "sent" : "error");
    } catch {
      setStatus("error");
    }
  }

  if (status === "sent") {
    return <p>Thanks! Your message is on its way.</p>;
  }

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="name" placeholder="Your name" />
      <input type="email" name="email" placeholder="[email protected]" required />
      <textarea name="message" placeholder="What's on your mind?" required />
      <button type="submit" disabled={status === "sending"}>
        {status === "sending" ? "Sending…" : "Send"}
      </button>
      {status === "error" && <p>Something went wrong. Please try again.</p>}
      <input name="company_website" type="text" tabIndex={-1} autoComplete="off"
        style={{ position: "absolute", left: "-10000px" }} aria-hidden="true" />
    </form>
  );
}

cómo funciona

Tres pasos de principio a fin.

01

Crear una bandeja

Una bandeja por aplicación con endpoint y email al instante.

02

Añade el componente

Pega ContactForm.tsx, sustituye ID y úsalo en ruta, pie o modal. Cambia el diseño como quieras.

03

Recibe avisos

Añade Discord, Slack, email o webhook. Los mensajes avisan donde ya estás.

por qué mailcontact

Pensado para funcionar con React.

Sin acoplar un servidor a tu SPA

Vite y CRA generan archivos. CORS permite hablar directamente con mailcontact sin proxy ni funciones adicionales.

Confirmaciones que encajan con React

fetch y useState mantienen al visitante: desactiva al enviar y muestra agradecimiento al confirmar. Sin abandonar el router.

Tu JSX, tu sistema de diseño

Es un formulario, no widget ni iframe. Usa Tailwind, CSS Modules, styled-components o tus estilos.

preguntas frecuentes

React + mailcontact: tus preguntas resueltas

¿De verdad no necesito servidor ni función serverless?

Correcto. El endpoint acepta POST de otros orígenes (CORS abierto), así que el navegador envía directamente a mailcontact. Puedes desplegar React como archivos estáticos, sin funciones.

¿Cómo muestro el éxito en la misma página?

Envía con fetch como en el ejemplo y cambia un useState si la respuesta es correcta. El envío nativo devuelve JSON, sin redirección configurable; fetch es lo adecuado para una SPA.

¿Qué campos acepta y cuáles son los límites?

Envía email y message (obligatorios), name y subject (opcionales) y company_website vacío (obligatorio), como FormData o JSON. Hay un límite de 20 peticiones por minuto e IP y 64 KB por cuerpo, suficiente para contacto.

¿Puedo utilizar react-hook-form o mi biblioteca de componentes?

Sí. Usa react-hook-form, campos controlados o una biblioteca. La petición debe incluir email, message y company_website vacío. name y subject son opcionales. MailContact.send() gestiona la verificación.

relacionado

También funciona con

Una bandeja por cada proyecto de React 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.