AI app builder · Replit Agent
Skip the backend work for your Replit Agent contact form
Replit Agent doesn't just build a form — it scaffolds a full Express backend and provisions a Postgres database for your whole app. That's useful for real app data, but for "email me when someone submits this form" it usually means asking Agent to add Nodemailer, store SMTP credentials as Replit Secrets, and maybe a submissions table in that database you'll never query again. A lot of backend for five fields and an inbox notification.
Point the contact form at a PostTo endpoint instead and skip that entirely — no SMTP provider to configure, no secrets to store for this one feature, no table to migrate. Paste one prompt into Replit Agent's chat and it rewires the existing form; the rest of your backend stays untouched.
Free plan, no credit card required.
Three steps, a few minutes
Create an endpoint
Sign up free and create a PostTo endpoint with your destination email. You get an endpoint URL immediately — no Replit integration or API key exchange required.
Paste the prompt into Replit Agent
Give Agent the prompt below with your endpoint URL swapped in. It rewires the existing form's submit logic to call PostTo instead of scaffolding a mailer — layout, fields, and the rest of your app untouched.
Test it in the webview
Submit the form from Replit's webview preview. The email lands in your inbox, and the submission shows up in the PostTo dashboard immediately.
The prompt and the code
Replace YOUR_TOKEN
with the endpoint URL from your dashboard.
Update the contact form so submitting it sends the data to PostTo instead of
building a new email feature. Don't add Nodemailer, an SMTP provider, or a
submissions table for this — just POST the form fields as JSON to
https://postto.dev/api/v1/send/YOUR_TOKEN from the client, with a
"Content-Type: application/json" and "Accept: application/json" header. Show
the existing success state if the response is ok, and the existing error
state otherwise. Add a hidden "_hp" honeypot input that real visitors never
see. Keep all other current fields, validation, and styling unchanged.
export function ContactForm() {
const [status, setStatus] = useState<'idle' | 'sent' | 'error'>('idle');
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const payload = Object.fromEntries(new FormData(e.currentTarget));
const res = await fetch('https://postto.dev/api/v1/send/YOUR_TOKEN', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify(payload),
});
setStatus(res.ok ? 'sent' : 'error');
}
return (
<form onSubmit={handleSubmit}>
<input type="text" name="name" placeholder="Name" required />
<input type="email" name="email" placeholder="Email" required />
<textarea name="message" required />
{/* Honeypot: bots fill this in, humans never see it */}
<input type="text" name="_hp" tabIndex={-1} autoComplete="off" style={{ display: 'none' }} />
<button type="submit">Send</button>
</form>
);
}
import crypto from 'node:crypto';
import type { Express } from 'express';
export function registerRoutes(app: Express) {
app.post('/api/contact', async (req, res) => {
const ts = Math.floor(Date.now() / 1000).toString();
const body = JSON.stringify(req.body);
const sig = crypto
.createHmac('sha256', process.env.POSTTO_SECRET!)
.update(`${ts}.${body}`)
.digest('hex');
const response = await fetch('https://postto.dev/api/v1/send/YOUR_TOKEN', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-PostTo-Timestamp': ts,
'X-PostTo-Signature': sig,
},
body, // exact bytes that were signed
});
res.status(response.status).json(await response.json());
});
}
Good to know
Skip Nodemailer and SMTP secrets
Replit Agent's default answer to "add a contact form" is often a Nodemailer transport plus SMTP host/user/pass stored as Replit Secrets, sometimes with a submissions table in the Postgres database it already provisioned. PostTo replaces all of that for this one feature — the fetch call above is the entire integration, and the rest of your app (auth, data, other routes) is untouched.
You already have a backend — signed mode is optional here
If you use the client-side snippet, treat it like a browser integration: plain endpoint URL and token only, never the signing secret. But unlike a client-only builder, Replit Agent ships a real Express server, so if you want the extra assurance, store the secret as a Replit Secret and have your existing route forward a signed request, as in the third snippet.
Spam protection is already wired in
The hidden _hp field is a honeypot — humans never see it, bots fill it in, and PostTo silently discards those submissions. Server-side baseline filtering (heuristics and optional AI classification) runs on every submission after that, so you don't need a CAPTCHA to start.
Frequently asked questions
- How do I stop Replit Agent from building its own mailer?
- Tell it explicitly, as in the prompt above. Left to its own defaults, Agent commonly reaches for Nodemailer plus SMTP secrets for any "send an email" request, since that's a common pattern for Node backends.
- Does this touch the Postgres database Replit provisioned?
- No. PostTo only replaces the "send this form as an email" piece — the rest of your app and database are untouched, and you're free to also log submissions to your own table if you want a copy, though it isn't required.
- Will this survive a Replit Deployment or further Agent edits?
- Yes — it's a plain fetch call (or a small Express route) inside your app code, so it persists through republishing, Replit Deployments, and further edits the same as any other code Agent writes.
- What does it cost?
- The free plan includes 50 submissions per month with the full dashboard — no credit card required. Paid plans start at $9/month.
Add a working form to your Replit Agent app today
Create an endpoint, paste the prompt, and see your first submission in the dashboard — all on the free plan.
Try PostTo free