Form Integration

Your Lovable contact form, minus the Supabase table

Ask Lovable for a contact form and it'll often offer a database table and an Edge Function to go with it. That's a lot of moving parts for a message box. Point the form at a Formbold endpoint instead and entries are stored, spam-checked and emailed. Free covers 250 submissions a month.

Contact Form for Lovable

What code should Lovable end up writing?

A component close to this one. It reads an optional VITE_FORMBOLD_URL from your .env file (Lovable keeps VITE_ values there, not in Secrets) and falls back to the endpoint. The full walkthrough with troubleshooting lives at /docs/lovable-contact-form.

lovable.tsx
// src/components/ContactForm.tsx
// Works in TanStack Start projects (new Lovable apps) and older React + Vite ones.
import { useState } from "react";

const FORMBOLD_URL =
  import.meta.env.VITE_FORMBOLD_URL ?? "https://formbold.com/s/FORM_ID";

type Status = "idle" | "sending" | "done" | "failed";

export function ContactForm() {
  const [status, setStatus] = useState<Status>("idle");
  const [note, setNote] = useState("");

  async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const formEl = event.currentTarget;
    setStatus("sending");

    try {
      const res = await fetch(FORMBOLD_URL, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        body: JSON.stringify(Object.fromEntries(new FormData(formEl))),
      });
      const body = await res.json().catch(() => ({}));

      if (!res.ok) throw new Error(body.message || `Formbold returned ${res.status}`);
      formEl.reset();
      setNote(body.message || "Got it. We reply within one business day.");
      setStatus("done");
    } catch (err) {
      setNote(err instanceof Error ? err.message : "Could not send. Try again.");
      setStatus("failed");
    }
  }

  return (
    <form onSubmit={onSubmit} className="mx-auto grid max-w-lg gap-4">
      <input name="name" placeholder="Your name" required className="rounded-lg border px-3 py-2" />
      <input name="email" type="email" placeholder="[email protected]" required className="rounded-lg border px-3 py-2" />
      <textarea name="message" rows={5} placeholder="What do you need?" required className="rounded-lg border px-3 py-2" />
      <button disabled={status === "sending"} className="rounded-lg bg-black px-4 py-2 text-white disabled:opacity-50">
        {status === "sending" ? "Sending..." : "Send"}
      </button>
      <p aria-live="polite" className={status === "failed" ? "text-red-600" : "text-green-700"}>
        {status === "done" || status === "failed" ? note : ""}
      </p>
    </form>
  );
}
How it works

How do I hook a Lovable form up to Formbold?

You'll spend longer waiting for Lovable to rebuild than on the setup itself.

1

Create the endpoint

In the Formbold dashboard, open All Forms and click Create New Form. Copy the https://formbold.com/s/FORM_ID address from Form Setup.

2

Paste this prompt into Lovable

"Connect my contact form to Formbold. On submit, send the fields as JSON with fetch to https://formbold.com/s/FORM_ID and set Accept: application/json. Keep the name attributes name, email and message. Show the reply message on success, show an error message when the response is not ok, and disable the button while it sends. Leave Supabase, Lovable Cloud and Edge Functions out of this form."

3

Publish, then submit from your phone

Click Publish (top right) so the site goes live on its lovable.app address, then send one real message. It shows up under Submissions in Formbold within seconds.

Features

What does Formbold handle that Lovable leaves to you?

Lovable is good at the UI. Everything below happens after the button is pressed, and Lovable won't do it unless you build a backend.

No Edge Function to babysit

The browser posts straight to Formbold, so there is no function log to check when a message goes missing.

Emails on the Free plan

Each message arrives with your input names as labels, so a field called budget shows up as budget. No upgrade needed.

Spam filter in one toggle

One switch in the form settings turns on Basic Spam Filter. If you also want a captcha, pick Custom reCAPTCHA, since this form posts with fetch.

Add Slack or Sheets later

Once you are on Starter, connect them from the form's Integrations tab. Nothing in the Lovable project changes.

Data you can pull back

The REST API and MCP server are on every plan, so you can read submissions from a script or from Cursor and Claude.

FAQs

Lovable questions, mostly about Supabase

Mostly Supabase, Secrets and the May 2026 stack change.

Yes. Lovable says apps created from May 13, 2026 use TanStack Start, and older ones use React with Vite. A browser fetch to Formbold works the same in both.

Still have a question?

The docs cover setup, framework guides, integrations and spam protection, step by step.