Save HTML form data
You can submit forms to Val Town using the HTTP handler 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 handler Val
Write a val function that accepts a Request and returns a Response.
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.
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.