Ten years ago, "send a form to email" meant writing a mail.php file and uploading it next to your HTML. That is no longer true. Static sites, JAMstack hosting, and no-PHP environments (Netlify, Vercel, GitHub Pages, most modern shared hosts) are now the default — and a plain <form> tag can still land a submission in your inbox with zero backend code of your own.
Quick Answer
You do not need PHP to email yourself a form submission. Point your form's action attribute at a form-endpoint service (or your own serverless function) instead of a .php file, keep method="post", and give every field a name attribute. The endpoint receives the POST request and forwards it to your email. Build the exact markup with Form Studio — it generates accessible, correctly-attributed HTML in seconds.
Use the Free Tool
The fastest way to get this right is to not hand-write the form at all. Form Studio is a visual form builder that generates the HTML for you — labels correctly linked to inputs, every field given a name attribute (the single most common reason form-to-email setups silently fail), required-field validation, and a honeypot field for spam.
Open the contact form template pre-loaded with HTML output, set the Delivery tab to Custom endpoint, paste in your form-endpoint URL, and copy the generated code. It runs entirely in your browser — nothing about your form design is sent anywhere.
Why You No Longer Need PHP
mail.php worked because PHP has a built-in mail() function and most shared hosts ran PHP by default. Two things changed:
Static hosting became the default for most sites. Netlify, Vercel, Cloudflare Pages, and GitHub Pages don't run PHP at all — there is no server to execute a
.phpfile on.Form-to-email became a hosted service category. Providers now accept your form's POST request directly and handle validation, spam filtering, and email delivery for you — the same job
mail.phpused to do, minus the server you had to maintain.
The result: the HTML itself barely changes. You just point action at a URL that isn't yours instead of a PHP file that is.
The HTML a Form-to-Email Setup Actually Needs
Regardless of which endpoint service you use, the requirements are the same:
<form action="https://your-endpoint-provider.com/f/your-form-id" method="POST"> <label for="name">Your name</label> <input type="text" id="name" name="name" required> <label for="email">Email address</label> <input type="email" id="email" name="email" required> <label for="message">Message</label> <textarea id="message" name="message" required></textarea> <button type="submit">Send</button> </form>Three things matter more than anything else:
method="POST". Without it, the browser defaults toGET, which appends every field value to the URL as a query string — visible in the address bar, logged in server access logs, and rejected outright by most form-endpoint services.A
nameattribute on every field. The browser submitsname=valuepairs. An input with noname— easy to forget when hand-editing markup — is simply dropped from the submission. This is the single most common reason "my form isn't sending" tickets happen.The
actionURL matches your endpoint exactly, including the trailing form ID or key most providers issue per form.
Method 1: A Hosted Form-Endpoint Service
This is the right choice for the vast majority of static sites. You sign up with a provider, they give you a unique endpoint URL or email-verified action target, and your form POSTs directly to it — no code of yours runs on a server at any point.
What a good provider handles for you:
Parsing the POST body into field names and values
Forwarding a formatted email to your inbox
Basic spam filtering
A "thanks for submitting" redirect or JSON response
Rate limiting so a bot can't flood your inbox
What you're still responsible for: the HTML markup being correct, a honeypot or CAPTCHA if you want a second layer of spam defense, and telling the provider where to redirect after a successful submission.
Method 2: Your Own Serverless Function
If you're already deploying on Vercel, Netlify, or Cloudflare, you can skip the third-party provider and write a small API route that receives the POST body and calls an email-sending API (Resend, SendGrid, Postmark, or similar) directly:
// app/api/contact/route.js — a Next.js Route Handler export async function POST(request) { const data = await request.formData(); const payload = Object.fromEntries(data.entries()); await fetch('https://api.resend.com/emails', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.RESEND_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ from: 'forms@yourdomain.com', to: 'you@yourdomain.com', subject: `New submission from ${payload.name}`, text: JSON.stringify(payload, null, 2), }), }); return Response.redirect(new URL('/thanks', request.url), 303); }Point your form's action at /api/contact instead of a third-party URL. This gives you full control over formatting and where the email is sent, at the cost of maintaining a small amount of code and an email-provider API key. Form Studio's React and Next.js export formats generate a client component with a working fetch call already wired to a custom endpoint — set the Delivery tab to your API route and copy the code.
Adding Spam Protection
A public form endpoint attracts bots within days of going live. The cheapest effective defense is a honeypot field — an input that's invisible to real visitors (via CSS, not type="hidden", since some bots specifically skip hidden inputs) but visible to bots that fill in every field they find:
<div style="position: absolute; left: -9999px;" aria-hidden="true"> <label for="hp-website">Leave this field blank</label> <input type="text" id="hp-website" name="hp_website" tabindex="-1" autocomplete="off"> </div>On the receiving end, reject any submission where hp_website is non-empty. Form Studio's Behavior tab has a one-click honeypot toggle that adds this exact pattern to every export format automatically.
Step-by-Step Workflow
Step 1: Build your form fields in Form Studio or write the HTML by hand, making sure every field has a name attribute.
Step 2: Sign up with a form-endpoint provider (or set up a serverless function) and get your endpoint URL.
Step 3: Set the form's action to that URL and confirm method="POST".
Step 4: Enable the honeypot field in the Behavior tab, or add one manually.
Step 5: Deploy the page and submit a real test — most providers require one verified test submission before they'll deliver to your inbox.
Step 6: Check spam/junk on the first real submission. Add the sending address to your contacts if it lands there.
Common Mistakes
Using mailto: as the form action. <form action="mailto:you@example.com"> does not send an email from your server — it tries to open the visitor's local email client with a pre-filled message. This fails silently on mobile, in webmail-only setups, and for any visitor without a configured desktop mail client. It is not a reliable submission method.
Forgetting name attributes. Covered above, but worth repeating: an unnamed field is invisible to the server no matter how correct everything else is.
Leaving method unset. The default is GET, which most endpoint providers reject outright with a 405 error.
Not testing the actual deployed page. A form that works on localhost can fail once deployed if the endpoint provider requires domain verification, or if a CSP header blocks the cross-origin POST.
No feedback after submission. If the page doesn't redirect or show a success message, users often resubmit — assuming it failed the first time. Configure a redirect or success message in your provider's dashboard, or handle the response in a fetch call if you're submitting via JavaScript.
Best Practices
Always add a honeypot field, even for low-traffic sites. Bots scan the web indiscriminately, not just popular targets.
Use
type="email"for email inputs. It gets you free client-side format validation and the right mobile keyboard.Keep field names descriptive (
email_address, notfield_2) — most endpoint providers use the field name as the label in the email they send you.Set a custom success message or redirect so users know the submission worked.
Verify your sending domain with your email provider if you're building a custom serverless function — unverified domains land in spam far more often.
Related Tools
Form Studio — Build and export a form in HTML, Tailwind, React, Next.js, and more
HTML Text Input Generator — Generate a single accessible text input
HTML Checkbox Generator — Generate an accessible checkbox group
JSON Formatter — Inspect the JSON payload your endpoint receives
The Developer Tools category has the full set of HTML and form utilities if you're building the rest of the page by hand.
FAQ
Can I just use mailto: instead of an endpoint?
Not reliably. mailto: action attributes depend on the visitor having a configured desktop email client and open it as a pre-filled draft rather than actually sending anything from the server. It fails completely for most mobile and webmail users. Use a real POST endpoint instead.
Do I still need PHP if my host supports it?
No — but you can still use it if you prefer. mail.php works fine on a PHP-capable host and is a valid alternative to a third-party endpoint. The point of this guide is for the (now much more common) case where you're on static or serverless hosting with no PHP runtime at all.
Is a form-endpoint service secure?
Reputable providers use TLS for the submission and store data according to their published retention policy — check it before sending anything sensitive. Never collect passwords, payment card numbers, or government ID numbers through a contact form regardless of the provider.
Why isn't my submission arriving in my inbox?
Check, in order: the name attributes on every field, that method="POST" is set, that the action URL exactly matches what your provider issued, that you completed the provider's one-time verification submission, and finally your spam folder.
Does this work on a fully static site with no server at all?
Yes — that's the entire point of a form-endpoint provider. Your HTML page can be 100% static; the provider's server does the receiving and forwarding.
Send Your First Form Now
Build the form in Form Studio, set a custom endpoint in the Delivery tab, and copy the generated HTML. It's free, runs entirely in your browser, and produces the exact markup a form-endpoint provider expects.
Khushbu
Full-Stack Developer & Founder
I build tools I wish existed — fast, free, and private. Every tool runs in your browser because I believe your data should stay yours.
Put this guide into practice

