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:

  1. Change the form action

    Replace youremail@example.com with your real email address.
    For example:

    action="https://formsubmit.co/bitemyke01@gmail.com"
  2. Every field must have a name attribute

    This is extremely important. If any field is missing a name, FormSubmit will not work correctly.

  3. 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 a name will show up in the email.

  4. 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
  • Email
  • 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
  • Email
  • 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

example.html
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)

example.html
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>
6
7<script>
8const form = document.getElementById('contactForm');
9
10form.addEventListener('submit', async (e) => {
11 e.preventDefault(); // Prevent default form submission
12
13 const name = document.getElementById('name').value.trim();
14 const email = document.getElementById('email').value.trim();
15
16 // Simple validation
17 if (!name) {
18 console.error("Name is required");
19 return;
20 }
21
22 const emailPattern = /^[^s@]+@[^s@]+.[^s@]+$/;
23 if (!emailPattern.test(email)) {
24 console.error("Invalid email address");
25 return;
26 }
27
28 // Prepare form data
29 const formData = new FormData();
30 formData.append('name', name);
31 formData.append('email', email);
32
33 try {
34 const response = await fetch('https://formsubmit.co/your@email.com', {
35 method: 'POST',
36 body: formData
37 });
38
39 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)

example.html
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>
6
7<script>
8const form = document.getElementById('contactForm');
9
10form.addEventListener('submit', (e) => {
11 e.preventDefault(); // Prevent default form submission
12
13 const name = document.getElementById('name').value.trim();
14 const email = document.getElementById('email').value.trim();
15
16 // Validation
17 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 }
26
27 // Prepare form data
28 const formData = new FormData();
29 formData.append('name', name);
30 formData.append('email', email);
31
32 // send xhr req
33 const xhr = new XMLHttpRequest();
34 xhr.open('POST', 'https://formsubmit.co/your@email.com', true);
35
36 //handle successful send
37 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 };
44
45 //handle error
46 xhr.onerror = function () {
47 console.error("Request error");
48 };
49
50 xhr.send(formData);
51});
52</script>

HTML & JQuery (Ajax)

example.html
1<!-- Include jQuery first -->
2<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
3
4<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>
9
10<script>
11$(document).ready(function() {
12$('#contactForm').on('submit', function(e) {
13 e.preventDefault(); // Prevent default form submission
14
15 const name = $('#name').val().trim();
16 const email = $('#email').val().trim();
17
18 // Validation
19 if (!name) {
20 console.error("Name is required");
21 return;
22 }
23
24 const emailPattern = /^[^s@]+@[^s@]+.[^s@]+$/;
25 if (!emailPattern.test(email)) {
26 console.error("Invalid email address");
27 return;
28 }
29
30 // Prepare form data
31 const formData = new FormData();
32 formData.append('name', name);
33 formData.append('email', email);
34
35 // AJAX request
36 $.ajax({
37 url: 'https://formsubmit.co/your@email.com',
38 type: 'POST',
39 data: formData,
40 processData: false, // Required for FormData
41 contentType: false, // Required for FormData
42 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

example.js
1import React, { useState } from "react";
2
3export default function ContactForm() {
4const [name, setName] = useState("");
5const [email, setEmail] = useState("");
6
7const handleSubmit = async (e) => {
8 e.preventDefault();
9
10 // Validation
11 if (!name.trim()) {
12 console.error("Name is required");
13 return;
14 }
15
16 const emailPattern = /^[^s@]+@[^s@]+.[^s@]+$/;
17 if (!emailPattern.test(email)) {
18 console.error("Invalid email address");
19 return;
20 }
21
22 // Prepare form data
23 const formData = new FormData();
24 formData.append("name", name);
25 formData.append("email", email);
26
27 try {
28 const response = await fetch("https://formsubmit.co/your@email.com", {
29 method: "POST",
30 body: formData,
31 });
32
33 if (response.ok) {
34 console.log("Form submitted successfully!");
35 // Optionally clear the form
36 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};
45
46return (
47 <form onSubmit={handleSubmit}>
48 <input
49 type="text"
50 name="name"
51 placeholder="Your Name"
52 value={name}
53 onChange={(e) => setName(e.target.value)}
54 required
55 />
56 <input
57 type="email"
58 name="email"
59 placeholder="Your Email"
60 value={email}
61 onChange={(e) => setEmail(e.target.value)}
62 required
63 />
64 <button type="submit">Send</button>
65 </form>
66);
67}

Vue 3 (composition API)

example.html
1<template>
2<form @submit.prevent="handleSubmit">
3 <input
4 type="text"
5 v-model="name"
6 placeholder="Your Name"
7 required
8 />
9 <input
10 type="email"
11 v-model="email"
12 placeholder="Your Email"
13 required
14 />
15 <button type="submit">Send</button>
16</form>
17</template>
18
19<script setup>
20import { ref } from 'vue';
21
22const name = ref('');
23const email = ref('');
24
25const handleSubmit = async () => {
26// Validation
27if (!name.value.trim()) {
28 console.error("Name is required");
29 return;
30}
31
32const emailPattern = /^[^s@]+@[^s@]+.[^s@]+$/;
33if (!emailPattern.test(email.value)) {
34 console.error("Invalid email address");
35 return;
36}
37
38// Prepare form data
39const formData = new FormData();
40formData.append('name', name.value);
41formData.append('email', email.value);
42
43try {
44 const response = await fetch('https://formsubmit.co/your@email.com', {
45 method: 'POST',
46 body: formData
47 });
48
49 if (response.ok) {
50 console.log("Form submitted successfully!");
51 // Optionally clear form
52 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 :).