# AI app builders

> Connect forms built by Lovable, Bolt, v0, Replit, Base44 or an AI code editor to Ikiform with one prompt, then check the code, test before a plan and set allowed domains.

Lovable, Bolt, v0, Replit and Base44 build the form you ask for, and AI code editors such as Cursor, Claude Code and Windsurf, now Devin Desktop, write one into your project. Where the submission goes is often left out: the button does nothing, or the tool offers to build a backend, a database table and an email service for it. One prompt points every form at your Ikiform endpoint instead, and Ikiform validates, filters spam, stores, emails and sends webhooks.

> Using Claude Code, Cursor or another agent that supports MCP? Connect the [Ikiform MCP server](https://ikiform.com/docs/mcp.md) and the agent can create the form and read its endpoint and fields itself.

## Prompts by tool

Each page has the prompt tuned for that tool, such as no Supabase function for Lovable or no Server Action for v0. The prompt below works in all of them.

- [Lovable](https://ikiform.com/for/lovable): No Supabase function or table.
- [Bolt](https://ikiform.com/for/bolt): No database or server function.
- [v0](https://ikiform.com/for/v0): A client component, no Server Action.
- [Replit](https://ikiform.com/for/replit): No server route or Replit Secret.
- [Base44](https://ikiform.com/for/base44): No entity, backend function or SendEmail.
- [Cursor](https://ikiform.com/for/cursor): Finds every form in the project.
- [Claude Code](https://ikiform.com/for/claude-code): Finds every form in the repository.
- [Windsurf](https://ikiform.com/for/windsurf): Also works in Devin Desktop.

## The prompt

Copy your endpoint from the form's overview in the dashboard and paste the prompt into the tool's chat with your endpoint in it. It works with any framework and names what the tool shouldn't build.

`Prompt`:

```text
Connect every form in this project to Ikiform so that each submission reaches me. The forms send straight from the browser. Do not build a backend, server route, API route, Server Action, database table, Supabase or edge function, email service or secret for this.

Endpoint: https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx

Find every form (contact, waitlist, signup, newsletter or any other). Check which framework and form library each one uses. Then, for each form:

1. Keep the form library, validation and components it already uses, such as react-hook-form or zod. Do not add a new dependency.
2. On submit, stop the page from reloading and send a POST request with fetch from the browser to the endpoint. If the framework renders on the server, put this in client-side code.
3. Send the form's fields as a JSON object with the headers "Content-Type: application/json" and "Accept: application/json". Keep every field the form already has and give each one a clear name, such as name, email and message.
4. If the form has an email field, also send its value as _replyto, so I can reply straight from the notification email.
5. Add a hidden text input named _gotcha as a spam trap. Move it off-screen instead of using display: none, give it tabindex="-1", autocomplete="off" and aria-hidden="true", and send it with the other fields. Real visitors leave it empty.
6. While the request is sending, disable the submit button and show a loading state.
7. The response is JSON. Only when it has "ok": true, clear the form and replace it with a short thank-you message. Never show a success message before that.
8. If "ok" is false, show error.message near the submit button, and show each message in error.fields next to the field with that name. If the request fails or the response is not JSON, show "Something went wrong. Please try again."
9. Only put the endpoint in a public environment variable if the project already uses them in browser code. Otherwise keep it as a constant next to the form. Do not add a captcha, an API key or any secret. The endpoint is public and safe to use in the browser.

Keep my design, text and layout exactly as they are. Only change how the forms send. When you are done, list every form you changed.
```

## What to check in the code it writes

Open the code view, or the diff in your editor, and read each form's submit handler. It should match this:

| Look for | Why |
| --- | --- |
| A `POST` with `fetch` to your endpoint, from browser code | The post comes from the visitor's browser, so Ikiform sees your site as the origin. Ikiform allows CORS from any site, so no proxy is needed. |
| `Content-Type: application/json` and `Accept: application/json` | Ikiform answers with JSON the code can read, not a redirect or a hosted page. |
| `_replyto` set to the email field's value | Replying to the notification email reaches the visitor. |
| An empty `_gotcha` input moved off-screen, not hidden with `display: none` | It's the [honeypot](https://ikiform.com/docs/html.md#honeypot). Some bots skip inputs that are hidden. Names starting with `_` are never stored. |
| The thank-you message only when the JSON has `"ok": true` | Otherwise a held, refused or failed post still shows thanks. |
| `error.message` near the button, and `error.fields` next to each field | Visitors see why a post was refused, such as a missing required field. |
| No new API route, Server Action, database table, Supabase or edge function, email SDK or secret | None of them are needed, and each is code you'd have to host and maintain. |
| The endpoint as a constant, or in a public variable such as `VITE_` or `NEXT_PUBLIC_` | A server-only variable or a Replit Secret is `undefined` in the browser, so every post fails. |

To compare against working code, see [Plain JavaScript](https://ikiform.com/docs/guides/javascript.md) and [React](https://ikiform.com/docs/guides/react.md). [JavaScript and fetch](https://ikiform.com/docs/frameworks.md#responses) shows the response format.

## Test before you pick a plan

Setting up is free, and Ikiform treats a builder's preview as a live site. Until you pick a plan, only posts from your own machine and **Send test submission** are delivered:

| Where you test | Before a plan |
| --- | --- |
| **Send test submission** on the form's page in the dashboard | Always delivered, and doesn't count toward usage |
| Your machine: `localhost`, `127.0.0.1`, `[::1]`, `*.localhost` or `*.local`, any port | Delivered, the first 50 each month; then `402 test_limit_reached` |
| The builder's preview, or the published site | Held for 30 days, up to 100 a month. Visitors are told the form isn't live yet. Picking a plan releases them. |

- Cursor, Claude Code and Windsurf run the project on your machine, so posts from the dev server's `localhost` address are delivered.
- A Bolt or v0 project you download or push to GitHub runs locally the same way, with the project's dev command.
- Agents that test the app by clicking through it can submit your forms. Each of those posts is held like a visitor's. Ask the tool not to submit forms while it tests.

See [Testing without a plan](https://ikiform.com/docs/limits.md#testing-without-a-plan) for the full rules.

## Allowed domains

Allowed domains are empty by default, which accepts posts from any site. If you set them, list every host the form runs on. A listed domain also matches its subdomains, but a builder's preview host is usually a sibling of your published address, not a subdomain of it.

| Where the form runs | Add to Allowed domains |
| --- | --- |
| Lovable, published | `your-app.lovable.app`, and your custom domain if you have one |
| Lovable preview | Its own host, such as `id-preview--<project-id>.lovable.app` or `<project-id>.lovableproject.com`. Leave allowed domains empty until you publish, or add the exact host from the preview's address bar. |
| Bolt, published | `your-site.bolt.host`, and your custom domain if you have one |
| Bolt preview | Nothing. The preview runs inside your browser tab on a random `webcontainer-api.io` host that changes between sessions. |
| v0, deployed | `your-project.vercel.app`. Preview URLs such as `your-project-git-branch-team.vercel.app` don't match it; add the exact preview host while you test one. |
| v0 preview | Nothing. It runs on a `vusercontent.net` host that Vercel doesn't document and may change. |
| Replit, published | `your-app.replit.app`, and your custom domain if you have one |
| Replit development URL | Nothing. It has the form `<id>.<server>.replit.dev` and can change each time you reopen the app. |
| Base44, published | `your-app.base44.app`, and your custom domain if you have one |
| Base44 preview | The exact host from the preview's address bar, such as `preview--your-app.base44.app`, while you test there |
| Cursor, Claude Code or Windsurf, running locally | `localhost`. Ikiform compares the host name only, never the port. |
| Wherever you deploy a project from a code editor | The host your hosting gives you, and your custom domain |

- Never add `lovable.app`, `lovableproject.com`, `bolt.host`, `webcontainer-api.io`, `vercel.app`, `vusercontent.net`, `replit.app`, `replit.dev` or `base44.app` on its own. Every site on that host would match, including other people's.
- Before a plan, a post from a host that isn't listed is spam, and spam isn't held. It's dropped, not released when you pick a plan. Leave allowed domains empty while you test on a preview.

> Leave the form's spam check off. The prompt posts with `fetch`, so a form whose check is set to **Ikiform** answers `403 challenge_required` instead of showing the check page. The honeypot and spam scoring still run on every post.

## Test checklist

1. Paste the prompt with your endpoint, and read the list of forms the tool changed.
2. Check each submit handler against the table in [What to check](#check-the-code).
3. Click **Send test submission** on the form's page and confirm it reaches your dashboard and inbox.
4. Run the project locally if you can, submit each form, and confirm the submissions are listed in Ikiform.
5. Submit a form with an email that isn't valid while the form has [fields](https://ikiform.com/docs/fields.md) defined, and confirm the message appears next to the field.
6. Pick a plan, publish, and submit once from the published site.

## Troubleshooting

| What you see | Why | Fix |
| --- | --- | --- |
| The tool built an API route, database table, Supabase or edge function anyway | It fell back to its own backend for saving data | Send the prompt's first paragraph again, with its "Do not build" line, and ask it to remove what it added. |
| Visitors see `This form isn't live yet` | The workspace has no plan, so posts from the preview and the published site are held | Pick a plan to release them, or test with **Send test submission** or on `localhost`. |
| Submissions arrive under the spam filter with `origin_mismatch` | The page that posted isn't on the form's allowed domains | Add the host from the table above. With **Reject** chosen, the same posts get `403 origin_not_allowed` instead. |
| Nothing arrives, and the browser console shows a request to `undefined` | The endpoint is in a server-only environment variable or a Replit Secret, which the browser can't read | Put the endpoint in the code as a constant, or in a variable with your framework's public prefix. |
| The form says thanks, but nothing arrives | The thank-you message isn't gated on `"ok": true`, so it shows when a post fails or is held | Ask the tool to show thanks only when the response has `"ok": true`, and `error.message` otherwise. The browser's Network tab shows the real answer. |
| `402 test_limit_reached` on `localhost` | The workspace has no plan and already received 50 local test submissions this month | Pick a plan, or keep testing with **Send test submission**, which still works. |
| `403 challenge_required` | The form's spam check is set to **Ikiform**, which `fetch` posts can't show | Turn the check off for this form. |

## Related

- [HTML forms](https://ikiform.com/docs/html.md): Redirects, reserved fields and the honeypot.
- [Plain JavaScript](https://ikiform.com/docs/guides/javascript.md): `fetch` with inline errors.
- [Allowed domains](https://ikiform.com/docs/spam.md#allowed-domains): How origins are matched, and what a mismatch does.
- [Troubleshooting](https://ikiform.com/docs/troubleshooting.md): CORS, origin mismatches and 429s.
- [Spam protection](https://ikiform.com/docs/spam.md): Honeypot, scoring and the human check.
- [Site builders](https://ikiform.com/docs/guides/site-builders.md): The embed that works in any builder.
