splitforms.com
LEAD CAPTURE · CONTACT FORM TEMPLATE

Church Contact Form (Visitors, Prayer Requests)

A church website's contact form serves three very different visitors: the family checking you out before Sunday, the member with a prayer request, and the person asking about weddings or baptisms. One form, one routing dropdown, all three handled.

500/mo free·no card·works on any host
form.htmlhtml34 lines
01<form action="https://splitforms.com/api/submit" method="POST">
02 <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY">
03 <input type="hidden" name="subject" value="New detailed contact submission">
04
05 <label for="name">Full name *</label>
06 <input id="name" type="text" name="name" placeholder="Jane Builder" required>
07 <label for="email">Work email *</label>
08 <input id="email" type="email" name="email" placeholder="jane@company.com" required>
09 <label for="phone">Phone *</label>
10 <input id="phone" type="tel" name="phone" placeholder="+1 415 555 0142" required>
11 <label for="company">Company</label>
12 <input id="company" type="text" name="company" placeholder="Acme Inc">
13 <label for="reason">What's this about? *</label>
14 <select id="reason" name="reason" required>
15 <option value="">Choose…</option>
16 <option>Sales / pricing</option>
17 <option>Partnerships</option>
18 <option>Press / media</option>
19 <option>Support</option>
20 <option>Careers</option>
21 <option>Other</option>
22 </select>
23 <label for="message">Message *</label>
24 <textarea id="message" name="message" placeholder="Give us context — links, dates, deal size, anything we should know." required></textarea>
25
26 <!-- honeypot — bots fill every field -->
27 <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" autocomplete="off">
28
29 <button type="submit">Send</button>
30</form>
31
32<p style="margin-top:12px;font-size:11px;color:#888;text-align:right">
33 Powered by <a href="https://splitforms.com" style="color:#888;text-decoration:none" target="_blank" rel="noopener">splitforms</a>
34</p>
500
submissions / mo, free
6
fields, ready to ship
5
code outputs
60s
from copy to inbox
§ 01Why it mattersthe qualifying-fields argument

Most church websites run on a volunteer-maintained WordPress or Squarespace site, and the contact form is either broken or dumps everything into one unwatched inbox. The fix is a routing dropdown — 'I'm new', 'prayer request', 'weddings / baptisms', 'general question' — with each option BCC'd or webhooked to the right person. Prayer requests deserve confidentiality and a fast, personal reply; a first-time visitor inquiry deserves a warm welcome email before Sunday. One form can honour both.

Works on volunteer-maintained sites — no plugin, nothing to break, free forever.
✦ at a glance
  • Detailed contact form · 6 fields
  • HTML, JS, React, PHP, cURL outputs
  • One POST endpoint, no SDK
  • Honeypot + classifier, no CAPTCHA
§ 02Live previewinteractive · sandboxed · no key required

See exactly what your visitors see — and you’ll receive.

Left: the rendered form, fully interactive in a sandboxed iframe. Right: the email and dashboard view that lands the moment a visitor submits.

preview · church-contact-formlocalhost:3000
✦ what you’ll see in your inbox

Every submission becomes an email plus a dashboard row. The fields below are the exact payload your form will send. Reply-to is wired to the visitor’s email so hitting reply goes back to them.

dashboard · new submission14ms · 200 OK
SUBJECT · New detailed contact submission
Full name
Maya Iyer
Work email
maya@studio71.co
Phone
+1 415 555 0142
Company
Studio 71
What's this about?
Sales / pricing
Message
Loved your last open house in Hayes — looking for similar with parking. Pre-approved through Wells Fargo.

Iframe is sandboxed — submit doesn’t actually fire. Get your access key to wire it up live.

§ 03Three steps3 steps · ~60 seconds

Generate, embed, receive.

Three actions stand between you and your first lead. None of them require a backend, a database, or a CAPTCHA library.

STEP 01GENERATE

Add a reason dropdown

Options: 'I'm new / planning a visit', 'Prayer request', 'Weddings, baptisms & dedications', 'Volunteering', 'General question'. That one field routes everything.

Create your form
key=sk_live_••••••••
STEP 02EMBED

Route by ministry

Webhook or BCC each reason to the right inbox — prayer requests to the pastoral team, visitor inquiries to the welcome team, event questions to the office. Nobody's message sits unread for a week.

snippethtml
<form action="https://splitforms.com/api/submit" method="POST">
  …
</form>
STEP 03RECEIVE

Reply before Sunday

Set up an auto-responder that thanks the sender and tells visitors what to expect (service times, parking, kids check-in). A same-week personal follow-up is what turns a website visit into a pew visit.

inbox · 1 newjust now
FROM contact@yoursite.com
New detailed contact submission
Maya Iyer maya@studio71.co
Loved your last open house in Hayes — looking for similar with parking. Pre-approved through Wells Fargo.
§ 04Copy & ship5 languages · same endpoint

Five outputs. One backend.

HTML by default. Click open the language you ship in — every variant POSTs to the same /api/submit endpoint.

01HTMLform.html34 lines
<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 detailed contact submission">

  <label for="name">Full name *</label>
  <input id="name" type="text" name="name" placeholder="Jane Builder" required>
  <label for="email">Work email *</label>
  <input id="email" type="email" name="email" placeholder="jane@company.com" required>
  <label for="phone">Phone *</label>
  <input id="phone" type="tel" name="phone" placeholder="+1 415 555 0142" required>
  <label for="company">Company</label>
  <input id="company" type="text" name="company" placeholder="Acme Inc">
  <label for="reason">What's this about? *</label>
  <select id="reason" name="reason" required>
    <option value="">Choose…</option>
    <option>Sales / pricing</option>
    <option>Partnerships</option>
    <option>Press / media</option>
    <option>Support</option>
    <option>Careers</option>
    <option>Other</option>
  </select>
  <label for="message">Message *</label>
  <textarea id="message" name="message" placeholder="Give us context — links, dates, deal size, anything we should know." required></textarea>

  <!-- honeypot — bots fill every field -->
  <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" autocomplete="off">

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

<p style="margin-top:12px;font-size:11px;color:#888;text-align:right">
  Powered by <a href="https://splitforms.com" style="color:#888;text-decoration:none" target="_blank" rel="noopener">splitforms</a>
</p>
02JavaScriptform.js50 lines
<form id="lf-form">
  <label for="name">Full name *</label>
  <input id="name" type="text" name="name" placeholder="Jane Builder" required>
  <label for="email">Work email *</label>
  <input id="email" type="email" name="email" placeholder="jane@company.com" required>
  <label for="phone">Phone *</label>
  <input id="phone" type="tel" name="phone" placeholder="+1 415 555 0142" required>
  <label for="company">Company</label>
  <input id="company" type="text" name="company" placeholder="Acme Inc">
  <label for="reason">What's this about? *</label>
  <select id="reason" name="reason" required>
    <option value="">Choose…</option>
    <option>Sales / pricing</option>
    <option>Partnerships</option>
    <option>Press / media</option>
    <option>Support</option>
    <option>Careers</option>
    <option>Other</option>
  </select>
  <label for="message">Message *</label>
  <textarea id="message" name="message" placeholder="Give us context — links, dates, deal size, anything we should know." required></textarea>
  <button type="submit">Send</button>
</form>

<p style="margin-top:12px;font-size:11px;color:#888;text-align:right">
  Powered by <a href="https://splitforms.com" style="color:#888;text-decoration:none" target="_blank" rel="noopener">splitforms</a>
</p>

<script>
  document.getElementById('lf-form').addEventListener('submit', async (e) => {
    e.preventDefault();
    const data = new FormData(e.target);
    data.set('access_key', 'YOUR_ACCESS_KEY');
    data.set('subject', 'New detailed contact submission');

    const res = await fetch('https://splitforms.com/api/submit', {
      method: 'POST',
      body: data,
      headers: { Accept: 'application/json' },
    });

    const json = await res.json();
    if (json.success) {
      e.target.reset();
      alert('Sent!');
    } else {
      alert('Error: ' + (json.message || 'Try again'));
    }
  });
</script>
03React / Next.jsForm.tsx65 lines
'use client';

import { useState, type FormEvent } from 'react';

export default function ContactDetailedForm() {
  const [status, setStatus] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle');

  async function onSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setStatus('sending');

    const data = new FormData(e.currentTarget);
    data.set('access_key', 'YOUR_ACCESS_KEY');
    data.set('subject', 'New detailed contact submission');

    const res = await fetch('https://splitforms.com/api/submit', {
      method: 'POST',
      body: data,
      headers: { Accept: 'application/json' },
    });

    const json = await res.json();
    setStatus(json.success ? 'sent' : 'error');
    if (json.success) e.currentTarget.reset();
  }

  if (status === 'sent') return <p>Thanks — we&rsquo;ll be in touch.</p>;

  return (
    <>
    <form onSubmit={onSubmit}>
      <label htmlFor="name">Full name *</label>
      <input id="name" type="text" name="name" placeholder="Jane Builder" required />
      <label htmlFor="email">Work email *</label>
      <input id="email" type="email" name="email" placeholder="jane@company.com" required />
      <label htmlFor="phone">Phone *</label>
      <input id="phone" type="tel" name="phone" placeholder="+1 415 555 0142" required />
      <label htmlFor="company">Company</label>
      <input id="company" type="text" name="company" placeholder="Acme Inc" />
      <label htmlFor="reason">What's this about? *</label>
      <select id="reason" name="reason" required>
        <option value="">Choose…</option>
        <option>Sales / pricing</option>
        <option>Partnerships</option>
        <option>Press / media</option>
        <option>Support</option>
        <option>Careers</option>
        <option>Other</option>
      </select>
      <label htmlFor="message">Message *</label>
      <textarea id="message" name="message" placeholder="Give us context — links, dates, deal size, anything we should know." required />

      <button type="submit" disabled={status === 'sending'}>
        {status === 'sending' ? 'Sending…' : 'Send'}
      </button>

      {status === 'error' && <p>Something went wrong. Try again.</p>}
    </form>

      <p style={{ marginTop: 12, fontSize: 11, color: '#888', textAlign: 'right' }}>
        Powered by <a href="https://splitforms.com" target="_blank" rel="noopener" style={{ color: '#888', textDecoration: 'none' }}>splitforms</a>
      </p>
    </>
  );
}
04PHPsubmit.php28 lines
<?php
// Drop into a PHP page. Receives a form POST and proxies it to splitforms.com.
// Useful when you want to add server-side validation or rate limiting.

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $allowed = ['name', 'email', 'phone', 'company', 'reason', 'message'];
    $payload = ['access_key' => 'YOUR_ACCESS_KEY'];
    $payload['subject'] = 'New detailed contact submission';

    foreach ($allowed as $f) {
        if (isset($_POST[$f])) $payload[$f] = $_POST[$f];
    }

    $ch = curl_init('https://splitforms.com/api/submit');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json']);
    $response = curl_exec($ch);
    $status   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    header('Content-Type: application/json');
    http_response_code($status);
    echo $response;
    exit;
}
?>
05cURLtest.sh10 lines
curl -X POST https://splitforms.com/api/submit \
  -H "Accept: application/json" \
  -d "access_key=YOUR_ACCESS_KEY" \
  -d "subject=New detailed contact submission" \
  -d "name=Jane Builder" \
  -d "email=jane@example.com" \
  -d "phone=+15555555555" \
  -d "company=Jane Builder" \
  -d "reason=Sales / pricing" \
  -d "message=Hello from cURL" 

Replace YOUR_ACCESS_KEY with the key from your dashboard. That’s the only edit.

§ 04bUse this template with…25 frameworks · same backend

One template. Every framework.

The same field set works on every framework splitforms supports. HTML, React, Next.js, Vue, Astro, Hugo, WordPress — same POST, same backend.

Detailed contact form for HTML/forms/html/contact-detailedDetailed contact form for Next.js/forms/nextjs/contact-detailedDetailed contact form for React/forms/react/contact-detailedDetailed contact form for Vue/forms/vue/contact-detailedDetailed contact form for Astro/forms/astro/contact-detailedDetailed contact form for Svelte/forms/svelte/contact-detailedDetailed contact form for Webflow/forms/webflow/contact-detailedDetailed contact form for Carrd/forms/carrd/contact-detailedDetailed contact form for WordPress/forms/wordpress/contact-detailedDetailed contact form for Tailwind CSS/forms/tailwind/contact-detailedDetailed contact form for AJAX (vanilla JS)/forms/ajax/contact-detailedDetailed contact form for Hugo/forms/hugo/contact-detailedDetailed contact form for Gatsby/forms/gatsby/contact-detailedDetailed contact form for Eleventy/forms/eleventy/contact-detailedDetailed contact form for SvelteKit/forms/sveltekit/contact-detailedDetailed contact form for Framer/forms/framer/contact-detailedDetailed contact form for Nuxt/forms/nuxt/contact-detailedDetailed contact form for Alpine.js/forms/alpinejs/contact-detailedDetailed contact form for Bootstrap/forms/bootstrap/contact-detailedDetailed contact form for Jekyll/forms/jekyll/contact-detailedDetailed contact form for Vite/forms/vite/contact-detailedDetailed contact form for JavaScript/forms/javascript/contact-detailedDetailed contact form for Cloudflare Pages/forms/cloudflare/contact-detailedDetailed contact form for Netlify/forms/netlify/contact-detailedDetailed contact form for Vercel/forms/vercel/contact-detailed
§ 06FAQ4 answered

Things people ask before they ship.

Direct answers, no marketing fluff. Missing one? Email hello@splitforms.com.

01Are prayer requests kept confidential?
Submissions go only to the email addresses you configure — they're not published anywhere. splitforms stores them encrypted at rest, and you can delete any submission permanently from the dashboard. Add a 'share with prayer team / pastor only' checkbox if your congregation expects that distinction.
02Does this work on our Squarespace / Wix / WordPress site?
Yes — the form is plain HTML and posts to splitforms, so it works in a Squarespace code block, a Wix HTML embed, or a WordPress page with no plugin. Church sites maintained by volunteers especially benefit: nothing to update, no plugin to break.
03Can we use this as a digital connect card?
Yes — that's the 'I'm new' path. Add optional fields for how they found you and whether they'd like someone to reach out. Many churches put a QR code on the physical bulletin pointing at the same form so Sunday visitors and website visitors land in one place.
04Can submissions go to multiple staff members?
Yes — add BCC addresses in the dashboard, or webhook into a shared Slack / Planning Center workflow. Most churches send everything to the office admin plus the reason-specific lead (pastor for prayer, welcome-team lead for visitors).
✻ ✻ ✻

Ship your church contact form (visitors, prayer requests) in 60 seconds.

500 free submissions per month. No credit card. Copy the snippet, paste your access key, watch leads land in your dashboard.

Get free access key →Browse all 75 templates →
founders pricing locked in · early access open