DEV Community

yehuda
yehuda

Posted on

How to add a contact form to your static site — no backend, no monthly fee

I got tired of paying for form services or spinning up a backend just to handle contact form submissions. So I built RG Forms — a contact form endpoint backed entirely by a Google Sheet you own. No server, no monthly fee, no third-party storing your data.

The idea

Most form tools store your submissions on their servers. You pay monthly, you depend on their uptime, and your data lives in their database. RG Forms does the opposite: every submission goes straight into a Google Sheet in your own Google Drive, sent by an Apps Script that you own and control.

RG Forms provisions that sheet and script for you in about 90 seconds. After that, your endpoint runs forever at no cost — completely independent of any RG Forms server.

Built for static sites

If you host on GitHub Pages, Netlify, Vercel, Cloudflare Pages, or just plain HTML on a CDN, you've hit this wall: there's no backend to receive a form POST. The usual workarounds are a paid form service, a serverless function you have to write and maintain, or standing up a whole backend just for a contact form.

RG Forms is built exactly for this. Your endpoint is a plain HTTPS URL you POST to straight from client-side JavaScript — no build step, no serverless function, no server of any kind. Drop the fetch call into your page and you're done. It pairs naturally with any static-site generator (Hugo, Jekyll, Astro, Eleventy, Next export) and any no-code builder that lets you add a snippet of JS. Your static site stays static; the form just works.

How it's built

RG Forms is a fully static web app. There's no RG Forms server, no database, no backend. Every API call during setup goes directly from your browser to Google using your own OAuth token.

Setup (one time, in your browser):

  Your Browser
      ├─── Google OAuth      ──▶  Short-lived token (memory only)
      ├─── Google Drive API  ──▶  Creates Sheet + Drive folder
      └─── Apps Script API   ──▶  Creates & deploys form handler

Live endpoint (after provisioning):

  Your Website / App
      └─── POST to script URL
                └─── Apps Script (in your Google account)
                          ├─── Appends row to Google Sheet
                          ├─── Sends email notification
                          └─── Returns { result: "success" }
Enter fullscreen mode Exit fullscreen mode

That OAuth token lives only in browser memory — never sent to an RG Forms server, never written to disk, gone when you close the tab.

What gets created in your Drive

  • A Drive folder named after your form
  • A Google Sheet with your column headers, plus a hidden _manifest tab the script reads on every request
  • An Apps Script web app deployed as a permanent HTTPS endpoint that appends rows and sends email

Posting to your endpoint

One detail worth calling out: post with Content-Type: text/plain. That avoids a CORS preflight Apps Script can't respond to, and the script still parses the body as JSON.

// POST directly from your static site — no server proxy needed.
const res = await fetch(FORM_SCRIPT_URL, {
  method: 'POST',
  headers: { 'Content-Type': 'text/plain' },
  body: JSON.stringify({
    tab: 'contact',
    fields, // { name, email, phone, message, ... }
  }),
});
const data = await res.json();
// { result: 'success' } or { result: 'error', error: '...' }
Enter fullscreen mode Exit fullscreen mode

The row appears in your Sheet and you get an email. That's it.

What's included

  • Email notifications on every submission, with a configurable subject
  • CC / BCC without exposing addresses in your frontend
  • Reply-to mapping — set a form field (like email) as the reply-to address
  • Honeypot spam protection — a hidden field bots fill out and the script silently discards
  • Multiple forms on one sheet as separate tabs sharing a single endpoint
  • Edit fields any time — add, remove, or relabel without reprovisioning
  • RGFORMS.md export — an AI skill file you can hand to Claude Code, Cursor, Copilot, or Windsurf so it wires up the form for you automatically

Limitations to know about

Apps Script on a free Google account caps email notifications at roughly 100/day. There's a one-time manual script authorization after provisioning (a Google requirement for scripts deployed via API), and the Apps Script API has to be enabled on your account first — RG Forms detects this and links you straight to the toggle. Spam protection is honeypot-only, so high-traffic forms should add reCAPTCHA on the frontend.

Why I built it

Formspree, Typeform, and similar tools are great but either cost money at scale or lock your data in their system. Since Apps Script runs inside Google's infrastructure under your own account, it's free within Google's generous quotas and your data never leaves your control.

Try it

rgforms.com — takes about 90 seconds to set up. There's a full how-it-works walkthrough too.

Would love feedback, especially if you've hit the same frustration with form backends on static sites.

Top comments (0)