splitforms.com
← Back to the journal

Add a Contact Form to Google Sites (2026 Guide)

Add a working contact form to Google Sites in minutes — embed an HTML form that stores submissions, emails you, and blocks spam. No Apps Script needed.

Start free — 500 submissions totalSee pricing →No credit card. Paid plans from $5/mo.
Short answer
Google Sites has no native contact form — only an Insert → Forms option that embeds a separate Google Form. To get a real, on-brand contact form, click Insert → Embed → Embed code and paste an HTML form that posts to splitforms. Free tier is 500 submissions total, no Apps Script, email notifications on every plan. Grab a free access key and paste the snippet below.
Try it on your own form

Point any HTML form at one endpoint. 500 submissions total free, unlimited forms.

Create free account

Why Google Sites doesn't have a real contact form

Open the Insert panel in the new Google Sites editor and you'll find Text box, Images, Embed, Drive files, YouTube, Calendar — and Forms. That last one is the closest thing Google Sites has to a "contact form," and it isn't one: it drops in an iframe pointing at a separate Google Form, with Google's own styling, hosted on a different domain, writing rows into Google Sheets or the Forms responses tab.

That's fine for a quick internal survey. It's not great for a business contact page: no dashboard, no owner email the moment someone submits, no spam filtering beyond Google's account-wide checks, and a form that visually announces "this is a Google Form" instead of matching your site.

The fix doesn't require Apps Script or a Workspace add-on. Google Sites' Embed → Embed code option lets you paste raw HTML, including a <form> tag that posts straight to a hosted form backend — splitforms, in this guide.

Step 1: Get a splitforms access key (1 minute)

Go to splitforms.com/login, enter your email, paste the 6-digit code you receive, and you're in — the dashboard generates an access key on first load. Copy it; you'll paste it into the form snippet in Step 3.

The free plan is $0 for 500 submissions total, unlimited forms, email notifications on every plan, spam filtering (honeypot, time-trap, rate limiting, optional reCAPTCHA v2), and a hosted dashboard — no credit card. If you outgrow it, Starter is $1/month for 1,000 submissions plus signed webhooks and autoresponders, Pro is $5/month for 5,000, or $59 for the first three years, then $59/year, on the 3-Year plan. Full breakdown at /pricing.

Step 2: Open Insert → Embed → Embed code

In the Google Sites editor, open the page you want the form on and click into the section where it should live.

  1. Click Insert in the right-hand panel.
  2. Choose Embed from the list of insertable elements.
  3. A dialog opens with two tabs: Embed code and By URL. Click Embed code.
  4. Paste the HTML from Step 3 into the text box.
  5. Click Next, then Insert.

Google Sites drops the embed onto the page as a resizable box. Drag its handles to size it — the box doesn't auto-grow to fit content that changes after the page loads, which matters once you get to the submit behavior in Step 4.

Step 3: Paste the form snippet

Because Google Sites renders Embed-code content inside its own sandboxed frame, the snippet needs to be self-contained — it can't inherit fonts or colors from the rest of your Google Site the way a same-origin code block on some other builders can. So this snippet carries its own minimal CSS. Replace YOUR_ACCESS_KEY with the key from Step 1.

<style>
  .sf-form {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
    max-width: 480px;
    margin: 0 auto;
    color: #1a1a1a;
  }
  .sf-form label { display: block; margin: 14px 0 6px; font-size: 14px; font-weight: 600; }
  .sf-form input, .sf-form textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    border: 1px solid #d0d0d0;
    border-radius: 8px;
    font: inherit;
    font-size: 15px;
  }
  .sf-form input:focus, .sf-form textarea:focus {
    outline: 2px solid #1a73e8;
    border-color: transparent;
  }
  .sf-form button {
    margin-top: 16px;
    padding: 12px 22px;
    background: #1a73e8; /* swap for your brand color */
    color: #fff;
    border: 0;
    border-radius: 8px;
    font-weight: 700;
    font-size: 15px;
    cursor: pointer;
  }
  .sf-form button:disabled { opacity: 0.6; cursor: default; }
  .sf-thanks { display: none; text-align: center; padding: 40px 12px; font-family: inherit; }
</style>

<form id="sf-contact" class="sf-form" action="https://splitforms.com/api/submit" method="POST">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
  <input type="hidden" name="subject" value="New message from your Google Site" />

  <label>Name
    <input type="text" name="name" required autocomplete="name" />
  </label>

  <label>Email
    <input type="email" name="email" required autocomplete="email" />
  </label>

  <label>Message
    <textarea name="message" rows="5" required></textarea>
  </label>

  <!-- Honeypot: bots fill this, real visitors never see it -->
  <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" autocomplete="off" />

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

<div id="sf-thanks" class="sf-thanks">
  <p>Thanks — your message is in. We&apos;ll get back to you soon.</p>
</div>

<script>
  document.getElementById('sf-contact').addEventListener('submit', async function (e) {
    e.preventDefault();
    var form = e.target;
    var btn = form.querySelector('button');
    btn.disabled = true;
    btn.textContent = 'Sending...';
    try {
      var res = await fetch(form.action, { method: 'POST', body: new FormData(form) });
      var data = await res.json();
      if (data.success) {
        form.style.display = 'none';
        document.getElementById('sf-thanks').style.display = 'block';
      } else {
        btn.disabled = false;
        btn.textContent = 'Send message';
      }
    } catch (err) {
      btn.disabled = false;
      btn.textContent = 'Send message';
    }
  });
</script>

Three things worth knowing about this snippet:

  • Honeypot (botcheck) is a hidden checkbox. Bots that scrape and auto-fill every field trip it; real visitors never see it or fill it. More on this in honeypot vs reCAPTCHA.
  • The <script> block intercepts the submit and swaps the form for a thank-you message in place, instead of letting the browser navigate. See Step 4 for why that matters inside an embedded box.
  • Field names are arbitrary. Add name="phone" or name="company" and splitforms includes them in the notification email automatically — no schema to configure.

A note on redirects inside an embedded frame

As of mid-2026, in our testing, Google Sites renders Embed-code HTML inside its own sandboxed frame, and a plain HTML form POST works fine from inside it — the request reaches splitforms.com/api/submit exactly as it would from any other page. What's worth watching is what happens after the submit: a plain redirect field navigates inside the embedded box, not the whole page, so a full-size thank-you page renders squeezed into whatever pixel size you set the embed to in Step 2 — usually looking broken.

Two ways around it, both compatible with the snippet in Step 3:

  1. Inline "thanks" swap (what Step 3 uses). A small fetch() call submits the form via JavaScript and, on success, hides the form and reveals a short message in the same box — splitforms' standard AJAX submit pattern, and the safer default for a small embedded frame.
  2. Plain POST with a compact redirect target. To skip JavaScript entirely, add <input type="hidden" name="redirect" value="https://yoursite.com/thanks" /> pointing at a minimal, embed-sized thank-you page rather than a full layout.

Either way, verify on the published site — Google Sites' editor preview doesn't always run embedded scripts identically to the live page, so behavior may vary between the two.

Step 4: Publish and test

  1. Click Publish in the top-right of the Google Sites editor (or Republish if the site is already live).
  2. Open the published URL in an incognito window, not the editor preview.
  3. Fill out the form with a real-looking test message, using an email address you can check.
  4. Click Send message. With the snippet above, the form should swap to the thank-you text in place within a second or two.
  5. Check your splitforms dashboard and the inbox tied to your splitforms account — both should show the submission almost immediately.

If the button spins forever or nothing happens, open the browser's developer console on the published page — a blocked-script or CORS error there usually points straight at the fix (see Troubleshooting below).

Step 5: Where submissions go

Every submission lands in two places automatically, with nothing to connect manually:

  • Your splitforms dashboard. Every submission is stored and searchable by date, form, or field content — a real lead list, not a Sheets export you have to remember to open.
  • Your inbox. Owner email notifications are included on every plan. Accepted submissions are saved to the dashboard before owner notification email is attempted; delivery time and inbox placement depend on provider and recipient settings.

Want the raw fields wired into your own inbox flow instead of splitforms'? See /form-to-email for how the email delivery pipeline works under the hood.

Step 6 (optional): Spam settings and autoresponders

The honeypot field in Step 3 already blocks the dumbest bots for free. splitforms layers two more checks server-side on every plan, no configuration needed: a time-trap that flags submissions sent implausibly fast after the form loaded, and rate limiting per access key. If you still see spam after that — unlikely for a low-traffic Google Site — you can turn on optional reCAPTCHA v2 from the dashboard.

On the Pro plan ($5/month), you can also turn on an autoresponder — an automatic confirmation email sent back to whoever filled out the form ("Thanks for reaching out, we'll reply within 1 business day"), configured once in the dashboard with no change to the embed snippet.

Custom HTML form vs. embedding a Google Form

Embedding a Google Form via Insert → Forms is still the default answer for a lot of Google Sites owners, and it's a reasonable one if all you need is to collect a few responses with zero setup. Here's the honest comparison:

  • Cost. Google Forms is free, no account tier required. splitforms is also free up to 500 submissions total — comparable for most contact pages.
  • Appearance. A Google Form looks like a Google Form: Google's fonts, Google's layout, hosted in its own iframe. A splitforms-backed HTML form is yours to style, matching your site's fonts and colors as shown in Step 3.
  • Spam filtering. Google Forms relies on Google's account-level spam signals with no per-form controls. splitforms adds a honeypot, a time-trap, rate limiting, and optional reCAPTCHA — visible and configurable per form.
  • Where responses go. Google Forms writes rows into Sheets — fine for tallying survey answers, less useful as a lead inbox. SplitForms saves accepted submissions to a searchable dashboard before attempting owner notification email; delivery time and inbox placement depend on provider and recipient settings.
  • Notifications. Google Forms notification emails are opt-in per form and easy to miss. SplitForms includes owner email notifications on every plan and attempts them after accepted submissions are saved; delivery timing and inbox placement depend on provider and recipient settings.

Quick internal feedback? Google Forms is fine. A contact page, quote request, or waitlist that represents your business's first impression is worth the extra five minutes for a form that matches your site and lands in a real dashboard.

Troubleshooting Google Sites-specific gotchas

  • The embed box shows a scrollbar or clipped content. Google Sites sizes the embed to whatever pixel dimensions you set when you inserted it and doesn't auto-grow. Drag the resize handles to add headroom, especially after adding extra fields.
  • Form appears in the editor but does nothing on the published page (or vice versa). Embedded scripts don't always run identically in preview versus the live page — always confirm on the published URL.
  • splitforms returns 401 Unauthorized. The access key has a typo, trailing whitespace, or a domain restriction excluding your Google Sites URL. Re-copy it and check Settings → Allowed Domains.
  • Nothing happens on submit, no visible error. Open the browser console on the published page — a missing action attribute or a fetch URL typo is the usual cause. Confirm it reads exactly https://splitforms.com/api/submit.
  • Email never arrives but the dashboard shows the submission. Check spam/junk first. Full diagnostic: contact form not working.

Still stuck? /docs has the full request contract, /api-reference covers response codes, and /faq answers plan and security questions.

Next steps

FAQ

Can you add a custom HTML form to Google Sites?

Yes. Open your page in the Google Sites editor, click Insert in the right-hand panel, choose Embed, then the Embed code tab, and paste an HTML <form> that posts to a hosted endpoint like splitforms.com/api/submit. Google Sites renders it inside its own embedded frame — no Apps Script, no plugin, and no Workspace admin approval needed for a basic form.

Does Google Sites have a built-in contact form?

No. Google Sites has an Insert → Forms option, but that only embeds a separate Google Form — it doesn't give you a native, styleable form block. It looks like a Google Form rather than your site, stores responses in Sheets instead of a lead dashboard, and its spam filtering is limited to Google's own account-level checks. Most people who want the form to match their site embed custom HTML instead.

Do I need Google Apps Script to make this work?

No. Apps Script is one way to build a custom backend, but it means writing and deploying script code, managing quotas, and maintaining it yourself. The HTML form in this guide skips Apps Script entirely — it POSTs directly to splitforms' hosted endpoint, which stores the submission, emails you, and runs spam filtering, all without any script project on your Google account.

Will the form redirect or reload the whole embedded box after I submit it?

It can, depending on how you configure it. A plain HTML POST with a redirect field navigates inside the embedded iframe, which looks odd if the destination page isn't sized for a small box. The snippet in this guide uses a small JavaScript fetch call instead, so a successful submission just swaps the form for a short 'thanks' message in place.

How does splitforms stop spam on a Google Sites form?

Three layers, stacked. A hidden honeypot field (name="botcheck") catches bots that fill every input they can see, including invisible ones. A time-trap checks how fast the form was submitted after it loaded — instant submits are almost always scripts. Rate limiting caps submissions per access key per window. Optional reCAPTCHA v2 is available if you still see spam after that, but most Google Sites forms don't need it.

What does this cost, and is there a free plan?

Free tier is $0 for 500 submissions total, unlimited forms, email notifications, the spam filtering above, a hosted dashboard, and no credit card. Starter is $1/month for 1,000 submissions plus signed webhooks and autoresponders. Pro is $5/month for 5,000 submissions. The 3-year plan is $59 for the first three years, then $59/year. Google Sites itself is free to publish on; splitforms only charges if you outgrow the free submission cap.

Where do my Google Sites form submissions actually go?

Accepted submissions are saved in your SplitForms dashboard, searchable by date, form, or field content. Owner email notifications are included on every plan and attempted after saving; delivery time and inbox placement depend on provider and recipient settings. There is no Sheets export step or manual integration to configure.

Can I test the form before my Google Site is fully published?

Partially. Google Sites' in-editor preview renders most embeds, but embedded iframes and their scripts don't always behave identically to the live, published version — as of mid-2026, in our testing, form submits are more reliable to verify after publishing than in preview. Always do one real test submission on your published, live URL before you consider the form done.

Related articles

More practical guidance from tutorials.

Browse the journal →
Tutorials

How to Add a Contact Form to a Website Built with Claude, Cursor, Lovable, v0 or Bolt

AI-generated contact forms do nothing on submit because there is no backend. Fix it with one…

11 min readRead →
Tutorials

FormData in JavaScript: Submit Forms with fetch (2026 Guide)

The complete FormData guide: reading form fields, appending files, sending multipart and url…

9 min readRead →
Tutorials

Custom Auto-Responder Emails for HTML Forms (HTML + CSS, 2026)

Design fully branded auto-responder emails for your HTML forms: paste your own HTML/CSS temp…

9 min readRead →

Explore this topic

Start with the overview, then move into focused guides.

OverviewContact Forms for Every FrameworkStart here →GuideContact Form for Next.jsRead →GuideContact Form for ReactRead →GuideContact Form for VueRead →ReferenceContact form guideOpen →

Building forms with ChatGPT, Claude, Cursor, or v0? Connect the native MCP server and give your agent a production form backend.

Explore the MCP server →

Give your form a production backend.

One endpoint adds delivery, spam filtering, storage, and integrations. Start with 500 submissions total for free.

Create free accountRead the docs →
Secure checkoutSSL encryptionPrivacyProtected
VISAAMERICANEXPRESSstripe