---
title: "Deploy Serverless Forms"
description: "NodeJS app to send HTML form submissions by email"
category: "Automation"
url: https://railway.com/deploy/serverless-forms
---

# Deploy Serverless Forms

NodeJS app to send HTML form submissions by email

**[Deploy Serverless Forms on Railway](https://railway.com/template/serverless-forms)**

- **Creator:** Candide's Projects
- **Category:** Automation
- **Total deploys:** 6

## Template content

### serverless-forms

- **Source:** lexoyo/serverless-forms
- **Public domain:** Yes

## Documentation

# Deploy and Host Serverless Forms on Railway

## Common Use Cases

This project is made for those who need to add forms to their static page or static website.

## About Hosting

It is a simple nodejs server which forwards all POST submission by email, inspired by [formspree](http://formspree.io/).

## Why Deploy

No database, 100% server (nodejs or Docker), just sends the submissions by email.

100% free software. No data is kept on the server. No tracking. No cookies.

Suggestion: thanks to the webhook feature you can automate the management of the submissions with tools like [Huginn](https://github.com/huginn/huginn), [node-red](https://nodered.org/), [codeberg](https://codeberg.org/about/)/[forgejo](https://forgejo.org/)...

Links:

* [repository on github](https://github.com/lexoyo/serverless-forms/)
* [package on npm](https://www.npmjs.com/package/serverless-form)

## Usage

### Test with the example form

Go to your Railway site to see the HTML form which resides in `public/form.html`.

Submit the form, and it will send you an email with the content of the form.

### Customize the form

Create any html form on your web page which will POST data to the server. You'll receive all the form fields in the submission by email.

Example:

```html
<form action="http://localhost:8080" method="post">
  <input required="" placeholder="Name" type="text">
  <input required="" placeholder="Email" name="email" type="email">
  <textarea required="" placeholder="Message" name="message"></textarea>
  <button type="submit">Send</button>
</form>
```

For this to work, the server must be started with the following environment variables:

```bash
TO="email1@example.com,email2@example.com" \
EMAIL_USER="username" \
EMAIL_PASS="*******" \
EMAIL_HOST="mail.gandi.net" \
EMAIL_PORT=587 \
npm start
```

### Tokens

This is a feature to avoid spam. You can use tokens in place of email addresses to avoid spam. The form will be expected to have a hidden field with the name `token` and the value of the token. If the token is found in the object, the email will be sent to the corresponding email address(es).

Start the app with the following environment variable
  
  ```bash
  TO='{"token1":"email1@example.com","token2":"email2@example.com,email3@example.com"}' \
  # ... other env variables
  npm start
  ```

Add a hidden field to your form with the name `token` and the value of the token you want to use.

```html
<form action="http://localhost:8080" method="post">
  <input value="token1" name="token" type="hidden">
  <input required="" placeholder="Name" type="text">
  <input required="" placeholder="Email" name="email" type="email">
  <textarea required="" placeholder="Message" name="message"></textarea>
  <button type="submit">Send</button>
</form>
```

### Thank you page

You can provide a link to a thank you page in the form. The server will redirect to this page after the form is submitted.

```html
<form action="http://localhost:8080" method="post">
  <input required="" placeholder="Name" type="text">
  <input required="" placeholder="Email" name="email" type="email">
  <textarea required="" placeholder="Message" name="message"></textarea>
  <button type="submit">Send</button>
  <input value="http://localhost:8080/thank-you.html" name="thanks" type="hidden">
</form>

```

For this to work, you need to start the server with the following environment variable:

```bash
REDIRECT=true \
REDIRECT_DOMAINS="localhost,your-domain.com" \
# ... other env variables
npm start
```

### Site name

You can provide a site name to be used in the email subject and body.

```html
<form action="http://localhost:8080" method="post">
  <input required="" placeholder="Name" type="text">
  <input required="" placeholder="Email" name="email" type="email">
  <textarea required="" placeholder="Message" name="message"></textarea>
  <button type="submit">Send</button>
  <input value="My Site" name="site" type="hidden">
</form>
```

## Install

### Docker

You can use the [docker image available on docker hub](https://hub.docker.com/repository/docker/lexoyo/serverless-forms) to run the serverless form server.

```
docker run -e EMAIL_USER="username" \
  EMAIL_PASS="********" \
  EMAIL_HOST="mail.gandi.net" \
  EMAIL_PORT=587 \
  TO="me@myemail.com" \
  -p 8080:8080 lexoyo/serverless-form
```

### Local install

Clone this repository and run the following commands:

```
$ npm install
$ EMAIL_USER="username" \
  EMAIL_PASS="*******" \
  EMAIL_HOST="mail.gandi.net" \
  EMAIL_PORT=587 \
  TO="me@myemail.com" \
  npm start
```

## Config

Here are all the environment variables you can use, check the file `lib/index.js` to see how the default values.

| Env var | description |
|---|---|
| MESSAGE | Message to displayed after the form submission. May contain HTML. |
| DISCLAIMER | Message added to the email sent to the recipient. May contain HTML. |
| TO | Email address(es) to send the form to (your email) |
| TO | A json object with tokens as keys and email addresses as values. The form will be expected to have a hidden field with the name `token` and the value of the token. If the token is found in the object, the email will be sent to the corresponding email address(es). |
| HOOK | URL to send the form data to as a POST request |
| HOOK | A json object with tokens as keys and `{ "url": "string", "headers": { "name": "value" } }` as values. The form can have an optional hidden field with the name `token` and the value of the token. If the token is found in the object, the form data will be sent to the corresponding URL. |
| FROM | Email address to use as sender address |
| REDIRECT | If set to true, the server will redirect to the URL provided in the `thanks` hidden field of the form |
| REDIRECT_DOMAINS | Comma separated list of domains for which the server will redirect to the URL provided in the `thanks` hidden field of the form |
| PORT | Port to listen to for form submissions |
| FORM | Path to the HTML file containing the example form, defaults to `public/form.html` |
| EMAIL_HOST | SMTP config: [see these options here](https://nodemailer.com/smtp/) |
| EMAIL_PORT | SMTP config: [see these options here](https://nodemailer.com/smtp/) |
| EMAIL_USER | SMTP config: [see these options here](https://nodemailer.com/smtp/) |
| EMAIL_PASS | SMTP config: [see these options here](https://nodemailer.com/smtp/) |
| THANKS_FIELD | Name of the field in the form which contains the URL to redirect to after the form submission |
| TOKEN_FIELD | Name of the field in the form which contains the token |
| SITE_FIELD | Name of the field in the form which contains the site name (used in the email subject) |
| HONEY_FIELD | Name of the field in the form which is a honeypot (if filled, the form will be considered as spam) |

## Dependencies for Serverless Forms
### Deployment Dependencies

Node JS, docker

## Similar templates

- [N8N Main + Worker](https://railway.com/deploy/n8n-main-worker) — Deploy and Host N8N with Inactive worker.
- [Evolution API with n8n](https://railway.com/deploy/evolution-api-with-n8n) — Build a WhatsApp automation platform with Evolution API, n8n & Postgres.
- [Postgres Backup](https://railway.com/deploy/postgres-s3-backups) — Cron-based PostgreSQL backup to bucket storage

Open this page in a browser: https://railway.com/deploy/serverless-forms
