← Back to Documentation

Collect Emails/Waitlist

Configure a Cloudflare Worker to collect and store email submissions from your launchpage. This guide covers both Wrangler CLI and UI-based setup methods.

Overview

Launchpage.xyz includes a contact form that submits visitor information. To receive these submissions, you'll deploy a Cloudflare Worker that:

Prerequisites

The Worker Repository

The contact form worker code is available at:

github.com/simplebytes-com/launchpage-contact-worker

Method 1: Deploy via Wrangler CLI (Recommended)

Step 1: Clone the Worker Repository

# Clone the worker repository
git clone https://github.com/simplebytes-com/launchpage-contact-worker.git
cd launchpage-contact-worker

# Install dependencies
npm install

Step 2: Install Wrangler

# Install Wrangler globally
npm install -g wrangler

# Login to Cloudflare
wrangler login

This will open a browser window for you to authenticate with Cloudflare.

Step 3: Create a KV Namespace

Create a KV namespace to store form submissions:

# Create production KV namespace
wrangler kv:namespace create "SUBMISSIONS"

# Note the ID that's returned - you'll need it next

Wrangler will output something like:

< Creating namespace with title "launchpage-contact-worker-SUBMISSIONS"
( Success!
Add the following to your wrangler.toml:
[[kv_namespaces]]
binding = "SUBMISSIONS"
id = "abc123def456..." 

Step 4: Configure wrangler.toml

Open wrangler.toml and update it with your settings:

name = "launchpage-contact"
main = "src/index.js"
compatibility_date = "2024-01-01"

# Add your Cloudflare Account ID
account_id = "YOUR_ACCOUNT_ID_HERE"

# KV namespace binding (use the ID from step 3)
[[kv_namespaces]]
binding = "SUBMISSIONS"
id = "YOUR_KV_NAMESPACE_ID_HERE"

# Custom domain route (optional)
# routes = [
#   { pattern = "contact.yourdomain.com/*", custom_domain = true }
# ]
Finding Your Account ID: Log into Cloudflare dashboard, select any domain, and look in the URL or right sidebar for your Account ID.

Step 5: Deploy the Worker

# Deploy to Cloudflare
wrangler deploy

# Your worker will be available at:
# https://launchpage-contact.YOUR_SUBDOMAIN.workers.dev

Step 6: Add a Custom Domain (Optional)

For a cleaner URL, add a custom domain:

# Add custom domain via CLI
wrangler domains add contact.yourdomain.com

Or configure in wrangler.toml:

routes = [
    { pattern = "contact.yourdomain.com/*", custom_domain = true }
]

Then redeploy:

wrangler deploy

Method 2: Deploy via Cloudflare Dashboard

Step 1: Create a KV Namespace

  1. Log into Cloudflare Dashboard
  2. Go to Workers & PagesKV
  3. Click "Create a namespace"
  4. Name it SUBMISSIONS
  5. Note the Namespace ID for later

Step 2: Create a Worker

  1. Go to Workers & PagesOverview
  2. Click "Create application""Create Worker"
  3. Name it launchpage-contact
  4. Click "Deploy"

Step 3: Add the Worker Code

  1. Click "Edit code" on your new Worker
  2. Copy the code from GitHub repository
  3. Paste it into the Worker editor
  4. Click "Save and Deploy"

Step 4: Bind the KV Namespace

  1. In your Worker, go to SettingsVariables
  2. Scroll to "KV Namespace Bindings"
  3. Click "Add binding"
  4. Variable name: SUBMISSIONS
  5. KV namespace: Select the namespace you created
  6. Click "Save"

Step 5: Add Custom Domain (Optional)

  1. Go to Triggers tab
  2. Click "Add Custom Domain"
  3. Enter your domain (e.g., contact.yourdomain.com)
  4. Add a CNAME DNS record if not on Cloudflare DNS

Update Your Launchpage HTML

Once your Worker is deployed, update the form action in your index.html:

<form class="email-form" id="emailForm" method="POST"
      action="https://YOUR-WORKER-URL">
    <!-- form fields -->
</form>

Replace YOUR-WORKER-URL with either:

Important: After updating the form action URL, redeploy your launchpage to your hosting platform (Netlify, Vercel, etc.) for changes to take effect.

Worker Configuration Options

Allowed Origins (CORS)

By default, the worker accepts requests from any origin. To restrict this, edit src/index.js:

// Current (allows all)
const allowedOrigins = ['*'];

// Restrict to specific domains
const allowedOrigins = [
    'https://yourdomain.com',
    'https://www.yourdomain.com',
    'https://anotherdomain.com'
];

Honeypot Field Name

The Worker uses a honeypot field named winnie_pooh to catch spam bots. This field should be hidden in your HTML and left empty by real users:

<!-- Honeypot field (invisible to users) -->
<div class="honeypot">
    <label for="winnie_pooh">Your favorite character (leave blank):</label>
    <input type="text" name="winnie_pooh" id="winnie_pooh"
           autocomplete="off" tabindex="-1">
</div>

Bots typically fill all fields, so if winnie_pooh has a value, the submission is silently rejected.

Viewing Submissions

Method 1: Via Wrangler CLI

# List all keys in KV namespace
wrangler kv:key list --namespace-id=YOUR_NAMESPACE_ID

# Get a specific submission
wrangler kv:key get "submission:example.com:1234567890" --namespace-id=YOUR_NAMESPACE_ID

Method 2: Via Cloudflare Dashboard

  1. Go to Workers & PagesKV
  2. Click on your SUBMISSIONS namespace
  3. Browse stored keys and values
  4. Click any key to view the submission data

Submission Data Format

Each submission is stored as JSON with this structure:

{
    "firstName": "John",
    "email": "john@example.com",
    "page": "example.com",
    "timestamp": "2025-01-15T10:30:00.000Z",
    "ip": "192.0.2.1",
    "userAgent": "Mozilla/5.0..."
}

The key format is: submission:{domain}:{timestamp}

Testing Your Setup

Test Submission

Test with curl to verify your Worker is working:

curl -X POST https://YOUR-WORKER-URL \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Test",
    "email": "test@example.com",
    "winnie_pooh": "",
    "page": "test.com"
  }'

You should receive:

{
    "success": true,
    "message": "Thank you for your submission"
}

Test Honeypot Protection

Verify spam protection by filling the honeypot:

curl -X POST https://YOUR-WORKER-URL \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Bot",
    "email": "bot@spam.com",
    "winnie_pooh": "I am a bot",
    "page": "test.com"
  }'

This should return success (to fool the bot) but NOT store the submission in KV.

Troubleshooting

Form submissions not being received?

KV binding errors?

CORS errors in browser?

Updating the Worker

To update the Worker code:

# Pull latest changes
cd launchpage-contact-worker
git pull origin main

# Redeploy
wrangler deploy

Cost Considerations

Cloudflare Workers and KV are very affordable:

For most launchpage use cases, you'll stay well within the free tier.

Pro Tip: Set up a separate Worker for each project or use environment variables to route submissions to different KV namespaces based on the domain.

Need help? Open an issue on GitHub or check the Cloudflare Workers documentation.

� Back to Documentation