Send Static Site Emails For Free
Have you ever found yourself in a situation where you’ve built a nice front-end application, it’s completely static, and you want to be able to send some data via email? Maybe it’s just from a simple contact form—but you don’t want to create a full backend or set up an SMTP server, because that kind of defeats the purpose of cheap, simple static hosting.
In this post, I’ll show you how to do exactly that using FormSubmit. This works for plain HTML, Vue, React, Next.js, or really any frontend framework.
What Is FormSubmit?
FormSubmit lets you send a POST request that includes your email address and the rest of your form data. They take that request and simply forward the submission directly to your email inbox.
No backend.
No SMTP server.
Completely free.
Creating the Form
To get started, head over to formsubmit.co and copy their demo form.
In my case, I’m using Next.js, so this ends up inside a React component—but I’ll keep everything written as plain HTML so it’s easy to follow no matter what framework you’re using.
Here’s the basic form:
<form action="https://formsubmit.co/your@email.com" method="POST"><input type="text" name="name" required><input type="email" name="email" required><button type="submit">Send</button></form>
Important Changes & Rules
There are a couple of small but critical things you need to update:
-
Change the form action
Replace
youremail@example.comwith your real email address.
For example:action="https://formsubmit.co/bitemyke01@gmail.com" -
Every field must have a
nameattributeThis is extremely important. If any field is missing a
name, FormSubmit will not work correctly. -
Add as many fields as you want
In my video, I added a textarea so users can send me a message, but you can add as many inputs as you need. Just be sire tp give it a proper
nameattribute. Anything with anamewill show up in the email. -
Do NOT Run on localhost If you are creating this via local development, you are probably building it on a fake url like localhost:8080. You can create the form here. But do not submit and test it here. Once you finish creating the form, push it to your production site, and test on the live URL. The reason for this is that FORMSUBMIT works by sending you an email validation based on the provided email and the site url.
Testing the Form
After deploying to production, fill out the form with some test data:
- Name
- Added Fields
First-Time Confirmation Email
The very first time you submit the form, you’ll receive a confirmation email from FormSubmit.
All you need to do is click Activate Form.
This step only happens once. It’s just to initialize the form. You will never see this confirmation email again.
Receiving Submissions
After activation, all future submissions will come straight to your inbox as regular emails.
Each email includes:
- Name
- Any additional fields you added to the form
If you add more fields later, they’ll automatically show up in the email as well.
Example Contact Form
You can see a live example of this setup on my website here:
https://bytemyke.com/contact
Code Examples:
HTML POST FORM
1<form action="https://formsubmit.co/your@email.com" method="POST">2 <input type="text" name="name" required>3 <input type="email" name="email" required>4 <button type="submit">Send</button>5</form>
HTML & Vanilla JS (Fetch API)
1<form id="contactForm">2<input type="text" name="name" id="name" placeholder="Your Name" required>3<input type="email" name="email" id="email" placeholder="Your Email" required>4<button type="submit">Send</button>5</form>67<script>8const form = document.getElementById('contactForm');910form.addEventListener('submit', async (e) => {11 e.preventDefault(); // Prevent default form submission1213 const name = document.getElementById('name').value.trim();14 const email = document.getElementById('email').value.trim();1516 // Simple validation17 if (!name) {18 console.error("Name is required");19 return;20 }2122 const emailPattern = /^[^s@]+@[^s@]+.[^s@]+$/;23 if (!emailPattern.test(email)) {24 console.error("Invalid email address");25 return;26 }2728 // Prepare form data29 const formData = new FormData();30 formData.append('name', name);31 formData.append('email', email);3233 try {34 const response = await fetch('https://formsubmit.co/your@email.com', {35 method: 'POST',36 body: formData37 });3839 if (response.ok) {40 console.log("Form submitted successfully!");41 } else {42 console.error("Form submission failed", response.statusText);43 }44 } catch (error) {45 console.error("Error submitting form", error);46 }47});48</script>
HTML & Vanilla JS (xhr)
1<form id="contactForm">2<input type="text" name="name" id="name" placeholder="Your Name" required>3<input type="email" name="email" id="email" placeholder="Your Email" required>4<button type="submit">Send</button>5</form>67<script>8const form = document.getElementById('contactForm');910form.addEventListener('submit', (e) => {11 e.preventDefault(); // Prevent default form submission1213 const name = document.getElementById('name').value.trim();14 const email = document.getElementById('email').value.trim();1516 // Validation17 if (!name) {18 console.error("Name is required");19 return;20 }21 const emailPattern = /^[^s@]+@[^s@]+.[^s@]+$/;22 if (!emailPattern.test(email)) {23 console.error("Invalid email address");24 return;25 }2627 // Prepare form data28 const formData = new FormData();29 formData.append('name', name);30 formData.append('email', email);3132 // send xhr req33 const xhr = new XMLHttpRequest();34 xhr.open('POST', 'https://formsubmit.co/your@email.com', true);3536 //handle successful send37 xhr.onload = function () {38 if (xhr.status >= 200 && xhr.status < 300) {39 console.log("Form submitted successfully!");40 } else {41 console.error("Form submission failed", xhr.statusText);42 }43 };4445 //handle error46 xhr.onerror = function () {47 console.error("Request error");48 };4950 xhr.send(formData);51});52</script>
HTML & JQuery (Ajax)
1<!-- Include jQuery first -->2<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>34<form id="contactForm">5<input type="text" name="name" id="name" placeholder="Your Name" required>6<input type="email" name="email" id="email" placeholder="Your Email" required>7<button type="submit">Send</button>8</form>910<script>11$(document).ready(function() {12$('#contactForm').on('submit', function(e) {13 e.preventDefault(); // Prevent default form submission1415 const name = $('#name').val().trim();16 const email = $('#email').val().trim();1718 // Validation19 if (!name) {20 console.error("Name is required");21 return;22 }2324 const emailPattern = /^[^s@]+@[^s@]+.[^s@]+$/;25 if (!emailPattern.test(email)) {26 console.error("Invalid email address");27 return;28 }2930 // Prepare form data31 const formData = new FormData();32 formData.append('name', name);33 formData.append('email', email);3435 // AJAX request36 $.ajax({37 url: 'https://formsubmit.co/your@email.com',38 type: 'POST',39 data: formData,40 processData: false, // Required for FormData41 contentType: false, // Required for FormData42 success: function(response) {43 console.log("Form submitted successfully!");44 },45 error: function(xhr, status, error) {46 console.error("Form submission failed:", error);47 }48 });49});50});51</script>
React / Next
1import React, { useState } from "react";23export default function ContactForm() {4const [name, setName] = useState("");5const [email, setEmail] = useState("");67const handleSubmit = async (e) => {8 e.preventDefault();910 // Validation11 if (!name.trim()) {12 console.error("Name is required");13 return;14 }1516 const emailPattern = /^[^s@]+@[^s@]+.[^s@]+$/;17 if (!emailPattern.test(email)) {18 console.error("Invalid email address");19 return;20 }2122 // Prepare form data23 const formData = new FormData();24 formData.append("name", name);25 formData.append("email", email);2627 try {28 const response = await fetch("https://formsubmit.co/your@email.com", {29 method: "POST",30 body: formData,31 });3233 if (response.ok) {34 console.log("Form submitted successfully!");35 // Optionally clear the form36 setName("");37 setEmail("");38 } else {39 console.error("Form submission failed", response.statusText);40 }41 } catch (error) {42 console.error("Error submitting form", error);43 }44};4546return (47 <form onSubmit={handleSubmit}>48 <input49 type="text"50 name="name"51 placeholder="Your Name"52 value={name}53 onChange={(e) => setName(e.target.value)}54 required55 />56 <input57 type="email"58 name="email"59 placeholder="Your Email"60 value={email}61 onChange={(e) => setEmail(e.target.value)}62 required63 />64 <button type="submit">Send</button>65 </form>66);67}
Vue 3 (composition API)
1<template>2<form @submit.prevent="handleSubmit">3 <input4 type="text"5 v-model="name"6 placeholder="Your Name"7 required8 />9 <input10 type="email"11 v-model="email"12 placeholder="Your Email"13 required14 />15 <button type="submit">Send</button>16</form>17</template>1819<script setup>20import { ref } from 'vue';2122const name = ref('');23const email = ref('');2425const handleSubmit = async () => {26// Validation27if (!name.value.trim()) {28 console.error("Name is required");29 return;30}3132const emailPattern = /^[^s@]+@[^s@]+.[^s@]+$/;33if (!emailPattern.test(email.value)) {34 console.error("Invalid email address");35 return;36}3738// Prepare form data39const formData = new FormData();40formData.append('name', name.value);41formData.append('email', email.value);4243try {44 const response = await fetch('https://formsubmit.co/your@email.com', {45 method: 'POST',46 body: formData47 });4849 if (response.ok) {50 console.log("Form submitted successfully!");51 // Optionally clear form52 name.value = '';53 email.value = '';54 } else {55 console.error("Form submission failed", response.statusText);56 }57} catch (error) {58 console.error("Error submitting form", error);59}60};61</script>
Overview
That’s really all there is to it. You now have a way to send emails from a static HTML, Vue, React, or Next.js site:
- No backend
- No SMTP
- Free
- Simple
If you found this helpful, be sure to subscribe to my YouTube channel for a wide variety of web dev tutorials, tips, and tricks!
Happy coding :).