Skip to content

Save HTML form data

You can submit forms to Val Town using the HTTP Val . You can place these forms on any page on the internet - or host the form directly on Val Town.

These examples show how to accept and store email addresses on Val Town. The email addresses are saved into a val, and you also get sent an email notification for each new signup.

Add a form to your website

Create a val that uses the HTTP Val

Write a val function that accepts a Request and returns a Response, or just fork the one below!

@user/saveFormDataRun in Val Town ↗
import { blob } from "https://esm.town/v/std/blob?v=11";
import { email } from "https://esm.town/v/std/email?v=11";
export const saveFormData = async (req: Request) => {
// Get existing list of submitted email addresses
let submittedEmailAddresses = await blob.getJSON("submittedEmailAddresses") as string[];
// If there were no email addresses stored, create an empty array
submittedEmailAddresses ??= [];
// Pick out the form data
const formData = await req.formData();
const emailAddress = formData.get("email") as string;
if (submittedEmailAddresses.includes(emailAddress)) {
return new Response("You're already signed up!");
}
// Send a notification email
email({ text: `${emailAddress} just signed up!`, subject: "New sign up" });
// Store form data
submittedEmailAddresses.push(emailAddress);
await blob.setJSON("submittedEmailAddresses", submittedEmailAddresses);
return new Response("Thanks! You're signed up!");
};

Add the form to your webpage

Copy your val’s Web endpoint URL using the menu (Endpoints > Copy web endpoint) and set it as the form’s action (this tells the form where to send its data when it’s submitted).

Below is a full HTML page example. If you are adding a form to an existing page just copy and paste the <form></form> block.

<!DOCTYPE html>
<html>
<head>
<title>Email Form</title>
</head>
<body>
<!-- Change the action here to your val's Express endpoint! -->
<form action="https://user-saveFormData.web.val.run" method="post">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required />
<br />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Host your form on Val Town

There are two ways to do this. You can write a val function that serves a webpage, and a separate val that accepts the form data - or you can write a single val that does both like the example below.

When a form is submitted, it sends a HTTP request with the POST method. When a user visits a webpage in their web browser, the server (your val function) gets sent a GET request.

You can check the HTTP method using req.method and change how your val function responds.

@user/renderFormAndSaveDataRun in Val Town ↗
import { blob } from "https://esm.town/v/std/blob?v=11";
import { email } from "https://esm.town/v/std/email?v=11";
import { thisWebURL } from "https://esm.town/v/stevekrouse/thisWebURL?v=2";
export const renderFormAndSaveData = async (req: Request) => {
// A visit from a web browser? Serve a HTML page with a form
if (req.method === "GET") {
return new Response(
`
<!DOCTYPE html>
<html>
<head>
<title>Email Form</title>
</head>
<body>
<form action="${thisWebURL()}" method="post">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<br>
<input type="submit" value="Submit">
</form>
</body>
</html>
`,
{ headers: { "Content-Type": "text/html" } },
);
}
// Get existing list of submitted email addresses
let submittedEmailAddresses = await blob.getJSON("submittedEmailAddresses") as string[];
// If there were no email addresses stored, create an empty array
submittedEmailAddresses ??= [];
// Pick out the form data
const formData = await req.formData();
const emailAddress = formData.get("email") as string;
if (submittedEmailAddresses.includes(emailAddress)) {
return new Response("You're already signed up!");
}
email({ text: `${emailAddress} just signed up!`, subject: "New sign up" });
// Store form data
submittedEmailAddresses.push(emailAddress);
await blob.setJSON("submittedEmailAddresses", submittedEmailAddresses);
return new Response("Thanks! You're signed up!");
};

See Web forms — Working with user data on the MDN Web Docs site for more help with forms. Forms are a basic part of the web - you don’t need a lot of front-end JavaScript to make them work.