Logotipo de Bitdoze

Cómo Añadir un Formulario de Contacto a Astro (Gratis, Sin Backend)

Aprende a añadir un formulario de contacto Astro gratis sin backend. Guías paso a paso para Web3Forms, formsubmit.co y OpnForm que envían notificaciones por email.

Dragos

47 min de lectura

Cómo Añadir un Formulario de Contacto a Astro (Gratis, Sin Backend)

Los sitios estáticos no pueden procesar envíos de formulario por sí solos. No hay servidor que maneje la petición POST, valide los datos o envíe un email. Incluso si añades comportamiento dinámico a un sitio Astro estático con un poco de código del lado del cliente, el propio formulario sigue necesitando un servicio externo que actúe de backend.

Esta guía cubre tres formas de añadir un formulario de contacto Astro funcional que te envía notificaciones por email cuando alguien lo envía. Sin backend, sin función serverless, sin base de datos de tu parte. La Opción 1 (Web3Forms) es la que recomiendo para la mayoría.

Flujo formulario-a-email: un visitante envía un formulario en una página Astro estática, una API de formulario-a-email lo procesa, y la notificación aterriza en tu bandeja

Las tres opciones funcionan en Astro 7 (release actual a finales de 2026, requiere Node 22.12 o más nuevo), y los precios y límites de abajo son los actuales.

Lo que este artículo no es

Ninguna de estas opciones requiere un backend que tú operes. Las opciones 1 y 2 son APIs de formulario-a-email: el formulario en tu página estática hace POST directamente a su endpoint. La opción 3 incrusta un constructor de formularios alojado. Si quieres escribir tu propio handler, ese es otro artículo.

Lo que necesitas:

  • Un sitio Astro. Si aún no tienes uno, empieza con la guía de blog gratis enlazada abajo
  • Una dirección de email donde deben aterrizar los envíos
  • Unos 5 minutos por opción, sin tarjeta para ninguno de los tiers gratis

Otros tutoriales de Astro:

Opción 1: Web3Forms - formulario de contacto Astro gratis (recomendado)

Web3Forms es una API de formulario-a-email. Creas un formulario en HTML, lo apuntas a su endpoint, y los envíos aterrizan en tu bandeja. Funciona sin servidor backend ni código del lado del servidor. Esa es toda la integración.

Planes actuales (según los publica Web3Forms):

Plan Precio Envíos/mes Subida de archivos Extras notables
Free 0 $ 250 No hCaptcha, honeypot, historial 30 días, 1 destinatario
Starter 49 $/año (solo anual) 5.000 No Todas las funciones Pro menos subidas y autoresponders
Pro 15 $/mes o 149 $/año 10.000 Sí (almacenamiento de archivos 30 días) Autoresponders, reCAPTCHA v3 / Turnstile, historial 1 año
Agency 39 $/mes o 399 $/año 20.000 Sí Hasta 10 destinatarios por formulario

Sin tarjeta requerida para el plan gratis.

Las subidas de archivos necesitan Pro

Este es el dato que la gente se equivoca más a menudo: el plan Starter (49 $/año) no incluye subida de archivos. Las excluye explícitamente. Si tu formulario necesita adjuntos, quieres Pro (15 $/mes o 149 $/año). Para un formulario de contacto normal de nombre/email/mensaje, el plan gratis basta.

Paso 1: Consigue una access key

Ve a web3forms.com e introduce tu dirección de email. Recibirás una access key. Esta clave no es un secret. Es seguro ponerla en código del lado del cliente. Actúa como un alias de tu dirección de email (su FAQ lo dice claro: “Access key is public”). No la trates como una API key que debas rotar.

Después, si aparece spam, abre app.web3forms.com y activa hCaptcha para el formulario. Más sobre eso abajo.

Paso 2: Crea el componente de formulario

Crea un componente Astro nuevo o añade el formulario a una página existente. Aquí un ejemplo mínimo:

astro
---
// src/pages/contact.astro
import Layout from "../layouts/Layout.astro";
---

<Layout title="Contact">
  <form
    action="https://api.web3forms.com/submit"
    method="POST"
    id="contact-form"
    data-astro-reload
    novalidate
  >
    <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY_HERE" />

    <!-- Honeypot spam protection -->
    <input type="checkbox" name="botcheck" style="display: none;" />

    <div>
      <label for="name">Name</label>
      <input type="text" name="name" id="name" required />
    </div>

    <div>
      <label for="email">Email</label>
      <input type="email" name="email" id="email" required />
    </div>

    <div>
      <label for="message">Message</label>
      <textarea name="message" id="message" rows="5" required></textarea>
    </div>

    <button type="submit">Send</button>

    <p id="result"></p>
  </form>
</Layout>

Reemplaza YOUR_ACCESS_KEY_HERE con la clave del paso 1.

El atributo data-astro-reload importa si usas el router del lado del cliente de Astro (ClientRouter de astro:transitions, antes la View Transitions API). Sin él, el envío del formulario puede fallar porque Astro intercepta la navegación. Este atributo y el evento astro:page-load de abajo no han cambiado en Astro 7. El mismo código funciona. Si tienes curiosidad por qué más llegó en Astro 7, mira los benchmarks de rendimiento de build de Astro 7.

Paso 3: Añade envío AJAX (opcional pero mejor UX)

El formulario HTML pelado funciona, pero redirige al usuario a una página de éxito de Web3Forms. Si quieres mostrar un mensaje de “enviado correctamente” sin salir de la página, añade este script:

astro
<script is:inline>
  document.addEventListener("DOMContentLoaded", () => {
    const form = document.getElementById("contact-form");
    const result = document.getElementById("result");

    form.addEventListener("submit", function (e) {
      e.preventDefault();
      const formData = new FormData(form);
      const object = Object.fromEntries(formData);
      const json = JSON.stringify(object);

      result.textContent = "Sending...";

      fetch("https://api.web3forms.com/submit", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        body: json,
      })
        .then(async (response) => {
          const data = await response.json();
          if (response.status === 200) {
            result.textContent = data.message;
          } else {
            result.textContent = data.message;
          }
        })
        .catch(() => {
          result.textContent = "Something went wrong.";
        })
        .then(() => {
          form.reset();
        });
    });
  });
</script>

Si usas el router del lado del cliente de Astro (ClientRouter), reemplaza el listener DOMContentLoaded por astro:page-load. Aquí la versión completa:

astro
<script is:inline>
  document.addEventListener("astro:page-load", () => {
    const form = document.getElementById("contact-form");
    const result = document.getElementById("result");

    if (!form) return;

    form.addEventListener("submit", function (e) {
      e.preventDefault();
      const formData = new FormData(form);
      const object = Object.fromEntries(formData);
      const json = JSON.stringify(object);

      result.textContent = "Sending...";

      fetch("https://api.web3forms.com/submit", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        body: json,
      })
        .then(async (response) => {
          const data = await response.json();
          if (response.status === 200) {
            result.textContent = data.message;
          } else {
            result.textContent = data.message;
          }
        })
        .catch(() => {
          result.textContent = "Something went wrong.";
        })
        .then(() => {
          form.reset();
        });
    });
  });
</script>

El guard if (!form) return; previene errores en páginas que no tienen el formulario de contacto. Con routing del lado del cliente, Astro re-ejecuta el evento astro:page-load en cada navegación, así que la comprobación importa.

Dos advertencias de AJAX

  1. El input oculto redirect (paso 4) no funciona con esta versión fetch(). Web3Forms documenta redirects solo para envíos de formulario HTML planos. Elige una: AJAX con mensaje inline, o un POST plano que redirige.
  2. El guard astro:page-load arregla errores de página ausente, no el doble-binding. Si este script se incluye en todo el sitio (un layout compartido), visitar la página de contacto dos veces puede adjuntar el handler de submit dos veces y disparar dos emails por envío. Acota el script a la página de contacto, o pon un flag data-bound en el formulario antes de adjuntar el listener.

Paso 4: Añade un redirect tras el envío (opcional)

En vez de AJAX, puedes redirigir a una página de gracias tras el envío. Añade este input oculto a tu formulario:

html
<input type="hidden" name="redirect" value="https://yourdomain.com/thanks" />

Web3Forms redirigirá al usuario ahí tras procesar el envío.

Límites de redirect en el plan gratis

El valor debe ser una URL absoluta (https://yourdomain.com/thanks, no /thanks). En el plan gratis, los redirects funcionan solo en el mismo dominio. Redirigir a un dominio distinto necesita un plan de pago. Y otra vez: esto solo aplica a la ruta HTML plana, no a la versión fetch() del paso 3.

Protección anti-spam gratis: hCaptcha vs honeypot

Los docs de Web3Forms ahora marcan el honeypot (botcheck) como obsoleto y “no recomendado”. Sigue funcionando y no cuesta nada, así que déjalo en el snippet base, pero la opción gratis que ellos mismos recomiendan es su hCaptcha zero-config.

hCaptcha (recomendado, gratis)

Añade el div del widget a tu formulario y el script de Web3Forms antes de </body>:

html
<form action="https://api.web3forms.com/submit" method="POST" data-astro-reload>
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY_HERE" />
  <div class="h-captcha" data-captcha="true"></div>
  <!-- ...fields... -->
  <button type="submit">Send</button>
</form>
<!-- before </body> -->
<script src="https://web3forms.com/client/script.js" async defer></script>

Luego activa hCaptcha para el formulario en el dashboard de Web3Forms. La etiqueta script por sí sola no hace nada hasta que el toggle está encendido.

El intercambio, directo de sus docs: los puzzles de hCaptcha “mayormente se sienten un poco difíciles para los usuarios”. Ese es el precio de gratis. reCAPTCHA v3 y Cloudflare Turnstile son más suaves pero requieren el plan Pro.

Honeypot (legacy, aún funciona)

Mantén el checkbox oculto del snippet base. Los bots que marcan cada casilla se delatan; los usuarios reales nunca lo ven:

html
<input type="checkbox" name="botcheck" style="display: none;" />

Web3Forms aún documenta botcheck y dice incluirlo “si no usas hCaptcha o reCaptcha”, pero sus docs ahora avisan de que es menos efectivo que un captcha real. Vale como primera línea de defensa, no como la única en un formulario público.

La access key es pública, así que planea para ello

Cualquiera que vea el código fuente puede coger tu access key y hacer POST al endpoint. Es así por diseño (es un alias de tu email, no una credencial). Existe filtrado de restricción-por-dominio pero es una función Pro. En el plan gratis, empareja la clave pública con hCaptcha en vez de confiar en la oscuridad.

Paso 5: Dale estilo al formulario

El markup de formulario de arriba es HTML pelado. Dalo estilo con tu enfoque preferido: Tailwind, CSS vainilla, o una librería de componentes. Web3Forms es solo un endpoint de API. No inyecta UI ni estilos.

Los docs de Web3Forms para Astro tienen un ejemplo completo con estilo Tailwind si quieres un punto de partida. Y ya que estás editando esta página de todas formas, es buen momento para añadir vídeos de YouTube a tu blog Astro o limpiar otras páginas del deploy.

Costes, límites y qué se rompe

El único gotcha real con Web3Forms gratis es el tope. Aquí el modo de fallo explicado:

A 250 envíos/mes, el formulario se para

Web3Forms manda un email de aviso al 90% de tu límite mensual, un aviso final al 100%, y luego los envíos nuevos se rechazan hasta el mes siguiente. No se encolan. Un formulario de contacto que deja de recibir correo en silencio es la forma clásica en que esto muerde, así que vigila esos emails de aviso o comprueba el dashboard si un sitio se queda callado.

Lo que necesitas por plan:

  • La mayoría de formularios de contacto: Free. 250/mes es de sobra para un sitio personal o página de negocio pequeña.
  • Subidas de archivos o autoresponders: Pro (15 $/mes o 149 $/año). Starter no los incluye.
  • Volumen mayor (5k/mes) sin subidas: Starter a 49 $/año es un valor decente.
  • Red de recuperación cuando un email se pierde: gratis guarda envíos 30 días, Pro 1 año. Ese historial es la diferencia entre “reenvíalo” y “se perdió” cuando un mensaje aterriza en spam.

La restricción de dominio (anti key-scraping) es solo-Pro, como se anotó arriba.

Opción 2: formsubmit.co (gratis, sin registro)

Formsubmit.co es otro servicio gratis de formulario-a-email. Sin registro requerido. Apuntas el atributo action de tu formulario a su endpoint con tu dirección de email, envías el formulario una vez, haces clic en un enlace de confirmación, y listo. Su homepage declara más de 6 millones de envíos de más de 400.000 sitios registrados.

Nada se guarda

formsubmit.co no guarda historial de envíos. Si el email no llega (dirección mal, filtro de spam agresivo), el envío se pierde. Web3Forms guarda 30 días en gratis; formsubmit no guarda nada. Además, sus docs avisan de que “imponen limitaciones técnicas de vez en cuando para filtrar bots”. No te prometas entrega ilimitada libre de spam de verdad, y mantén reCAPTCHA encendido.

Setup

astro
<form
  action="https://formsubmit.co/[email protected]"
  method="POST"
  data-astro-reload
>
  <input type="text" name="name" required />
  <input type="email" name="email" required />
  <textarea name="message" required></textarea>
  <button type="submit">Send</button>
</form>

Envía el formulario una vez. Revisa tu bandeja buscando un email de confirmación de Formsubmit.co. Haz clic en el enlace. Desde ese punto, todos los envíos van a tu email.

_captcha no es un flag de activación

reCAPTCHA está ENCENDIDO por defecto en cada formulario de formsubmit.co. El campo oculto _captcha lo desactiva cuando se pone a false. Si nunca añades el campo, ya tienes reCAPTCHA. No lo “actives” con value="true". Eso es un no-op en el mejor caso y confunde a la siguiente persona que lea tu plantilla.

Campos ocultos útiles

html
<!-- Redirect after submission -->
<input type="hidden" name="_next" value="https://yourdomain.com/thanks" />

<!-- CC another email (comma-separated for several) -->
<input type="hidden" name="_cc" value="[email protected]" />

<!-- Set subject line -->
<input type="hidden" name="_subject" value="New contact form submission" />

<!-- reCAPTCHA is ON by default; set to "false" to disable -->
<input type="hidden" name="_captcha" value="false" />

<!-- POST the submission as JSON to your own webhook -->
<input type="hidden" name="_webhook" value="https://yourdomain.com/hooks/form" />

<!-- Email template: "basic" (default), "clean", or "table" -->
<input type="hidden" name="_template" value="table" />

<!-- Auto-reply to the submitter (does not work with AJAX or with reCAPTCHA disabled) -->
<input type="hidden" name="_autoresponse" value="Thanks, we got your message." />

<!-- Drop submissions containing blacklisted phrases (max about 20) -->
<input type="hidden" name="_blacklist" value="spammy phrase, another one" />

Ojo a la advertencia de _autoresponse de sus docs: no envía para formularios que desactivan reCAPTCHA, y no envía para envíos hechos por AJAX/fetch. POST HTML plano con reCAPTCHA encendido es la única ruta donde el auto-reply funciona.

formsubmit.co vs Web3Forms

Función formsubmit.co Web3Forms
Envíos gratis Ilimitados (nada guardado) 250/mes (historial 30 días)
Registro requerido No (confirmación por email) Sí (solo email)
Protección anti-spam reCAPTCHA (encendido por defecto) hCaptcha (gratis, zero-config) + honeypot (desaconsejado)
Soporte AJAX Sí Sí
Redirect propio Sí (_next) Solo mismo dominio en gratis
Subida de archivos Reportada funcionando (verifica en tu formulario) Pro (15 $/mes o 149 $/año)
Webhooks _webhook (gratis) Pro
Almacenamiento de envíos Ninguno 30 días gratis / 1 año Pro

Ambos funcionan bien. formsubmit.co no tiene tope mensual ni cuenta que gestionar, pero no tienes red de seguridad cuando un email se pierde. Web3Forms tiene una API más limpia y guarda envíos 30 días en gratis, lo cual es útil si un email se pierde.

Opción 3: OpnForm (constructor de formularios open-source, autoalojable)

OpnForm es un constructor de formularios open-source con editor drag-and-drop. Diseñas el formulario visualmente, luego lo incrustas como un iframe.

Qué es gratis vs de pago (planes actuales): el plan gratis es más generoso de lo que era. Tienes formularios y envíos ilimitados, subidas de 10MB, lógica de formulario, campos computados, acceso API e integraciones básicas (email, webhook, Zapier, Google Sheets) en un workspace con branding de OpnForm. Pro cuesta 25 $/mes y añade quitar-branding, dominios propios, SMTP propio, notificaciones Slack/Discord/Telegram, captcha, analíticas y más. Business cuesta 67 $/mes (roles/permisos, límites de subida mayores) y Enterprise 220 $/mes (SSO, audit logs, almacenamiento externo).

Si te va bien que OpnForm envíe los emails por su servicio por defecto, el plan gratis funciona para formularios de contacto básicos. Si necesitas SMTP propio o captcha anti-spam, eso es Pro. O autoalójalo (siguiente sección).

Nota de precios

Las cifras de arriba son los precios de las tarjetas mensuales en opnform.com/pricing (comprobado octubre 2026). Su tabla comparativa muestra números algo distintos (29/79/250 $), que parecen equivalentes de facturación anual. Comprueba la página de precios antes de comprar, y cita el precio de tarjeta que veas.

Cómo usar OpnForm en Astro

  1. Crea una cuenta en opnform.com y construye tu formulario.
  2. Ve a la página Share del formulario y copia el código de embed.
  3. Pégalo en tu página Astro:
astro
---
// src/pages/contact.astro
import Layout from "../layouts/Layout.astro";
---

<Layout title="Contact">
  <iframe
    style="border:none;width:100%;"
    height="500px"
    src="https://opnform.com/forms/your-form-slug"
  ></iframe>
</Layout>

Ajusta el valor de height para encajar tu formulario. El enfoque iframe significa que no tienes control sobre el estilo del formulario. OpnForm lo maneja en el embed. El iframe también es inmune al router del lado del cliente de Astro, así que nada de gimnasia con data-astro-reload.

OpnForm form builder settings screen with email notification options

Autoaloja OpnForm con Docker

OpnForm es open source: el repo ahora es OpnForm/OpnForm (movido desde JhumanJ/OpnForm), unas 3,7k estrellas, open core AGPLv3, activamente mantenido. Autoalojar con Docker es la escotilla de escape del paywall Pro: SMTP propio y captcha se convierten en config que gestionas en vez de funciones de 25 $/mes. Incrustar una instancia autoalojada en Astro es idéntico. El mismo iframe, solo apuntando a tu propio dominio.

Enfoque de costes: un VPS pequeño corre todo el stack por más o menos 4-5 EUR/mes. Un Hetzner Cloud VPS (clase CX22) es de sobra para un formulario personal o de negocio pequeño, y tienes control total sobre dónde se guardan los envíos y qué relay SMTP manda el correo. Eso es más barato que Pro a 25 $/mes, y puedes correr una docena de contenedores más en la misma máquina.

Solo vale las piezas móviles extra si necesitas control de SMTP/captcha/branding. Si el plan alojado gratis te cubre, tómalo. Menos cosas que parchear.

Nota AGPLv3

La licencia open-core es AGPLv3 (el directorio enterprise está bajo una licencia aparte). Bien para uso propio y herramientas internas. Lee la licencia si planeas revender un servicio de formularios alojado construido sobre ella.

Para correrlo: clona el repo, docker compose up -d el stack, pon un reverse proxy delante, y apunta el src del iframe a tu instancia. Si ya corres Dokploy, el camino más corto es autoalojar OpnForm con Docker Compose en Dokploy como app compose.

¿Qué formulario de contacto Astro deberías usar?

¿Solo quieres emails en tu bandeja gratis? Usa Web3Forms. Lleva 5 minutos, el plan gratis maneja 250 envíos/mes (más que suficiente para un formulario de contacto), y hCaptcha es gratis cuando aparece el spam. El único gotcha real: al tope, los envíos se paran hasta el mes siguiente.

¿Necesitas envíos ilimitados y ninguna cuenta? Usa formsubmit.co. La confirmación por email de una vez es el único paso de setup. Acepta que nada se guarda. Si el correo se pierde, el envío se pierde.

¿Quieres un constructor visual con lógica y campos condicionales? Usa OpnForm. El plan gratis incluye notificaciones por email básicas e incluso subidas de 10MB. SMTP propio y captcha son Pro (25 $/mes), o autoalójalo y paga con tiempo de ops.

Aquí la comparación completa, las tres a la vez:

Función formsubmit.co Web3Forms OpnForm
Envíos gratis Ilimitados (sin almacenamiento) 250/mes (historial 30 días) Ilimitados
Registro Ninguno (confirmación por email) Solo email Sí
Anti-spam en gratis reCAPTCHA (encendido por defecto) hCaptcha gratis (zero-config) + honeypot (desaconsejado) Captcha es Pro
Redirect propio _next Solo mismo dominio en gratis n/a (formulario alojado)
Subida de archivos Reportada funcionando (verifica) Pro (15 $/mes o 149 $/año) Gratis (10MB)
Webhooks _webhook (gratis) Pro Gratis
Almacenamiento de envíos Ninguno 30 días gratis / 1 año Pro Guardado en OpnForm

Para un formulario de contacto simple que te envíe un email, Web3Forms es el mejor equilibrio de sencillez y funciones. Aquí el código mínimo otra vez:

astro
<form action="https://api.web3forms.com/submit" method="POST" data-astro-reload>
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY_HERE" />
  <!-- Honeypot still works, but Web3Forms docs now recommend hCaptcha instead -->
  <input type="checkbox" name="botcheck" style="display: none;" />
  <!-- Free hCaptcha: uncomment both lines, then enable it in the dashboard
  <div class="h-captcha" data-captcha="true"></div>
  -->
  <input type="text" name="name" placeholder="Name" required />
  <input type="email" name="email" placeholder="Email" required />
  <textarea name="message" placeholder="Message" required></textarea>
  <button type="submit">Send</button>
</form>
<!-- <script src="https://web3forms.com/client/script.js" async defer></script> -->
Consigue tu access key gratis de Web3Forms

Otras opciones, por completar: Formspree, StaticForms y Formspark son servicios alojados con el mismo modelo (el formulario hace POST a su endpoint). Si ya despliegas Astro con un adaptador y quieres poseer el handler, una función serverless más Resend (tier gratis de unos 100 emails/día) también funciona. Más piezas móviles, más control. Yo solo iría ahí después de que las opciones alojadas dejen de encajar.

Una vez la página de contacto esté sólida, lo siguiente que vale cablear en un sitio Astro es normalmente contenido: mejores opciones de headless CMS para Astro.

Verifica tu formulario antes de entregar

No confíes en el camino feliz. Corre esta checklist tras desplegar:

  • Envía un envío de prueba real y revisa tu bandeja y tu carpeta de spam. Los servicios de formulario-a-email aterrizan en spam más a menudo de lo que la gente espera. Mete al remitente en whitelist si hace falta.
  • Prueba la ruta AJAX con devtools abiertas. Espera HTTP 200 y un cuerpo JSON con un campo message de api.web3forms.com. Vigila la pestaña de red por si la petición se dispara dos veces. Ese es el bug de doble-binding de abajo.
  • Prueba con JavaScript desactivado. El fallback HTML plano debería seguir haciendo POST al endpoint (o redirigir, si configuraste uno). Si no hace nada, tu action de formulario o tu validación está rota.
  • Conoce tu historia de almacenamiento. formsubmit.co no guarda nada, así que un email perdido es un envío perdido. Web3Forms guarda 30 días en gratis. Si usas hCaptcha, confirma que el widget renderiza y el toggle del dashboard está encendido; la etiqueta script sola no hace nada.
El formulario no hace nada / navega fuera al usar routing del lado del cliente

Falta data-astro-reload en el formulario. El router del lado del cliente de Astro intercepta el submit y el POST nunca se comporta como un post de formulario normal. Añade el atributo y funciona.

El mensaje de éxito sale dos veces / el handler se dispara dos veces

El script se vincula en cada astro:page-load y el script está incluido en todo el sitio. El guard if (!form) return arregla errores de página ausente, no el doble-binding. Acota el script a la página de contacto o guarda con un flag data-bound antes de adjuntar el listener.

Los emails dejaron de llegar (Web3Forms)

Probablemente llegaste al tope de 250/mes. Los envíos se rechazan (no se encolan) hasta el mes siguiente. Comprueba el dashboard por uso, revisa tu carpeta de spam, y busca los emails de aviso del 90%/100%. Si necesitas subidas, recuerda que Starter no las incluye. Eso es Pro.

El redirect de gracias se ignora

O estás en la ruta AJAX (el campo redirect es solo-HTML-plano), o la URL es relativa (debe ser absoluta), o estás redirigiendo a otro dominio en el plan gratis (solo mismo dominio).

Los envíos de formsubmit.co desaparecen

El email de confirmación de una vez nunca se clicó. Reenvía el formulario y confirma. Además: _autoresponse silenciosamente no envía si desactivaste reCAPTCHA o si el envío va por AJAX. Y si el propio email se pierde, no hay almacenamiento de reserva.

FAQ

¿La access key de Web3Forms es un secret?

No. Es pública por diseño. Su FAQ dice “You do not need to hide the access key.” Es un alias de tu dirección de email, no una credencial. No la rotes como una API key. Sí empáreala con hCaptcha en un formulario público, ya que cualquiera puede copiarla de tu HTML.

¿Necesito un backend o función serverless?

No para las opciones 1 y 2. Ambas son APIs de formulario-a-email: el formulario en tu página estática hace POST directo a su endpoint y ellos mandan el email. OpnForm es un constructor de formularios alojado (o autoalojado) que incrustas. Solo necesitas tu propio handler si vas por la ruta DIY de adaptador + Resend.

¿Qué opción funciona con el routing del lado del cliente de Astro 7?

Las tres. El único gotcha está en los formularios HTML crudos (Web3Forms, formsubmit.co): añade data-astro-reload al formulario, y vincula los scripts AJAX en astro:page-load en vez de DOMContentLoaded. El iframe de OpnForm es inmune al router por completo.

¿Puedo tener subidas de archivos gratis?

Sí, con OpnForm (10MB en el plan gratis) o formsubmit.co (las subidas multipart están reportadas funcionando, así que verifica en tu formulario antes de confiar en ello). Web3Forms requiere Pro (15 $/mes o 149 $/año) para subidas; el plan Starter (49 $/año) las excluye explícitamente.

Eso es un formulario de contacto Astro funcional sin backend, gratis, en unos cinco minutos. Si aún estás construyendo el sitio, despliega un blog Astro en Cloudflare. El mismo código de formulario funciona igual dondequiera que se sirva el HTML.