· 6 min read Читать на русском

How to add a contact form to a static website without a backend.

How to add a contact form to a static website without a backend.

A static website is a fast, cheap, and reliable way to launch a landing page, promo page, documentation, or product site. But it has a typical problem: how to accept submissions if there is no backend?

For example, you have a site on Cloudflare Pages, GitHub Pages, Netlify, Vercel, S3/Selectel Object Storage, or any other static hosting. HTML, CSS, and JavaScript work great, but the feedback form itself cannot send data to Telegram, Email, or CRM.

In this article, we will discuss how to add a form to a static site without a backend, what options are available, and what to pay attention to so that submissions do not get lost.

Form on a static site without its own server

Problem

A regular HTML form looks simple:

<form>
  <input name="name" placeholder="Your name" />
  <input name="email" placeholder="Email" />
  <textarea name="message" placeholder="Message"></textarea>
  <button type="submit">Send</button>
</form>

But such a form does nothing useful until it has a handler.

To ensure that the submission actually reaches you, you need to:

If there is no backend, all of this has to be solved in another way.


Bad option: mailto:

Sometimes a form is attempted to be replaced with a link to an email:

<a href="mailto:sales@example.com">Write to us</a>

Or they create a form that opens the user's email client.

This is a bad option for lead generation.

Cons:

mailto: is suitable only as a backup contact, but not as the main submission form.


Option 1: write your own backend

The classic solution is to create your own endpoint:

POST /api/contact

It accepts the form data and sends it further.

Pros:

Cons:

This is fine for a large product. For a landing page, promo page, or MVP, it is often excessive.


Option 2: serverless function

You can create a form handler on Cloudflare Workers, Vercel Functions, Netlify Functions, or AWS Lambda.

Approximately like this:

export default {
  async fetch(request) {
    const data = await request.json()

    // validate data
    // send telegram notification
    // send email
    // return response

    return Response.json({ ok: true })
  }
}

Pros:

Cons:

Serverless is a good option for developers, but not always the best option for businesses, agencies, and teams that need to quickly launch many sites.


Option 3: form backend / lead capture service

A form backend is an external service that accepts POST requests from the form and delivers the submission to the desired channels.

The general principle:

Static Website → Form POST → Lead Capture Service → Telegram / Email / Webhook

On the site, only the HTML/JS code of the form remains. All backend logic is in the external service.

This approach is convenient if you need to:

Submission delivery scheme via Subscribe Service

Example of form integration

Below is an example of a simple form that sends a submission via JavaScript.

<form id="lead-form">
  <input name="name" placeholder="Your name" required />
  <input name="email" type="email" placeholder="Email" required />
  <textarea name="message" placeholder="Message"></textarea>

  <button type="submit">Send</button>
</form>

<script>
  const form = document.querySelector('#lead-form')

  form.addEventListener('submit', async (event) => {
    event.preventDefault()

    const formData = new FormData(form)

    const payload = {
      name: formData.get('name'),
      email: formData.get('email'),
      message: formData.get('message')
    }

    const response = await fetch('https://api.example.com/api/c1/sites/YOUR_SITE_KEY/submissions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    })

    if (!response.ok) {
      alert('Failed to send submission. Please try again.')
      return
    }

    form.reset()
    alert('Submission sent.')
  })
</script>

YOUR_SITE_KEY — the public key of the site. It is needed for the service to understand which site the submission belongs to.


What should be in a good form backend

Simply accepting a POST request is not enough. For a production scenario, additional things are important.

1. Domain verification

The service must understand that submissions are indeed coming from your site.

For this, you can use domain verification via a DNS TXT record.

Example:

subscribe-verification=abc123

This reduces the risk of someone connecting a foreign domain or starting to send junk on behalf of your site.


2. Captcha

A public form quickly starts receiving spam.

For simple forms, often a built-in math captcha is sufficient:

7 + 4 = ?

The user solves a simple problem, and the service checks the answer on the backend side.

Important:


3. Rate limiting

Even with captcha, it is worth limiting the frequency of submissions.

For example:

no more than 10 submissions per minute from one IP

Rate limiting protects against:


4. Delivery to multiple channels

A good scenario is to send the submission to several places at once:

Telegram + Email + Webhook

For example:


5. Retry on errors

Webhook or Email may temporarily not work.

For example:

If the service simply tries once and forgets the submission — this is poor reliability.

A retry mechanism is needed:

1st attempt → error
2nd attempt after 30 seconds
3rd attempt after 2 minutes
4th attempt after 10 minutes

This way, submissions are not lost due to temporary failures.

Form protection and reliable submission delivery

When to use a ready-made form backend

A ready-made service is especially useful if:

However, if the form is part of a complex product with a personal account, payments, custom business logic, and internal processes — it is better to create your own backend.


Conclusion

Adding a feedback form to a static site without a backend can be done in several ways:

For landing pages, static sites, promo pages, and MVPs, an external lead capture service is the best fit: the site sends the form to the API, and the service delivers the submission to Telegram, Email, or Webhook.

This way, you don't write a backend for just one form and still get reliable delivery, anti-spam, submission history, and integration control.


CTA

Want to accept submissions from your site without a backend?

Connect Form Hook: add the SDK, verify the domain, and receive leads in Telegram, Email, or Webhook.

← All posts