We Fixed Our Own Front Door
How a structured contact form qualifies B2B leads before the first call — and the technical implementation behind it.
TL;DR
- We replaced a bare mailto button with a full lead-qualifying intake that captures industry, company revenue, project intent, budget, the prospect's biggest challenge, and how they found us — all on submission, before any human reviews it — so the first call starts already briefed instead of exploratory.
- The first call is now a second conversation: we arrive knowing who's reaching out and why.
- Bot protection runs in two independent layers: Cloudflare Turnstile for human verification and a honeypot field that silently drains automated submissions.
- Built on Next.js, Resend, and
@marsidev/react-turnstile, and deployed across two brands from a single codebase.
We build reporting platforms, data environments, and operational systems for mid-market companies — the kind of work where showing up prepared and speaking the client's language is what separates a partner from a vendor.
So it was embarrassing to look at our own contact page.
A button. A mailto link. Clicking it opened Outlook on your local machine — if you had it installed. No form, no structure, no qualification. Nothing to tell us who was reaching out or why before we responded.
We built something real.
What a Lead-Qualifying Contact Form Actually Does
A lead-qualifying contact form collects structured information at submission — before any human reviews it — so the first conversation is informed rather than exploratory.
When a prospect submits our form, we know:
- Industry — Routes to relevant case studies; sets context immediately
- Company Revenue — Signals whether scope and budget are likely to align
- Project Intent — Hourly / Project / Retainer / Unsure; sets expectations before the call
- Biggest Challenge — Their words, not ours. Removes the "so what brings you in" opener
- Project Budget — Eliminates misaligned engagements before anyone spends time on them
- How They Found Us — Attribution; tells us what's working
The first call starts with: "You mentioned you're a $50M–$250M manufacturer trying to get Finance and Ops on the same numbers. Here's how we've handled that exact situation before."
That's the difference between a vendor and a partner.
Bot Protection: Two Independent Layers
Unprotected forms become junk inboxes within days. We implemented two independent protection mechanisms:
Honeypot field — A visually hidden input that legitimate users never see or interact with. Bots, which parse and fill forms programmatically, fill it automatically. If the field has any value on submission, the server returns a fake success response and discards the data. The bot thinks it worked. We never see it.
Cloudflare Turnstile — A frictionless human-verification challenge. No CAPTCHA puzzle, no image grid, no friction for real users. The widget loads and verifies passively. The submit button remains disabled until a valid challenge token is returned. If no token is present, the API route rejects the request before any email is sent.
Result: zero junk submissions since launch.
One Form. Two Brands.
The form serves two separate brands — Analytical Ants (consulting) and Analytical Solutions (the platform studio) — from a single React component. A site prop switches the field set: consulting inquiries capture revenue and budget; platform inquiries capture job title, team size, and product interest.
Same infrastructure. Different questions. One codebase. Exactly the kind of solution we'd build for a client.
Why Your Front Door Should Reflect How You Run
We tell operational executives the same thing every engagement: your systems should reflect how your business actually runs. Unstructured data creates unstructured decisions.
That applies to us too.
If you're reaching out, the form is doing its job before we ever respond.
Frequently Asked Questions
What is a lead-qualifying contact form?
A lead-qualifying contact form collects structured business information — industry, company size, budget, intent, and pain point — at the time of submission. This allows the receiving team to arrive at the first call already briefed, rather than using discovery time to gather basic context.
Why collect budget and revenue on a contact form?
Budget and revenue fields allow both sides to self-select appropriately. A prospect with a $5K budget for a $50K engagement saves everyone time by surfacing that mismatch before a call is scheduled. It also signals to the prospect that the firm takes scoped, accountable engagements seriously — not every inquiry is the right fit.
What is a honeypot field and how does it stop bots?
A honeypot is a form field that is concealed from real users but present in the HTML. Bots that programmatically fill forms will populate it; humans never encounter it. If the field has a value on submission, the server treats the request as automated and discards it — returning a fake success so the bot receives no signal to adapt.
How does Cloudflare Turnstile work without a CAPTCHA?
Cloudflare Turnstile analyzes browser signals — interaction patterns, environment fingerprinting, and behavioral cues — to determine whether the visitor is human. It issues a signed challenge token to legitimate users without requiring any puzzle interaction. The server verifies that token against Cloudflare's API before processing the submission.
What technology stack powers this form?
The form is built on Next.js (App Router), uses Resend for transactional email delivery, and Cloudflare Turnstile for bot protection. The React component is @marsidev/react-turnstile. The API route is a standard Next.js Route Handler that validates, verifies, and sends via the Resend SDK.
Technical Notes: For Developers
Skip this section if you're not building something similar.
The system is two files: a client component and a server-side API route.
components/ContactForm.tsx — Client component. Accepts a site prop that switches between field sets for different brands. State managed with useState. Includes a hidden honeypot field for bot detection. Cloudflare Turnstile via @marsidev/react-turnstile; the submit button stays disabled until onSuccess fires with a token.
app/api/contact/route.ts — POST handler. Order of operations: check honeypot → validate required fields → verify Turnstile token server-side → send via Resend. Email content is rendered as inline-styled HTML — no template engine needed.
Dependencies:
resend ^6.12.2
@marsidev/react-turnstile ^1.5.1Required env vars:
RESEND_API_KEY=re_...
TURNSTILE_SECRET_KEY=...
NEXT_PUBLIC_TURNSTILE_SITE_KEY=...To port: copy both files, install the two deps, set three env vars, verify your Resend sender domain, and confirm your Button component accepts variant="cta". The site prop is the only branching point — straightforward to extend with a third brand.
About the author — William Rodriguez is the founder of Analytical Ants, the delivery arm of Analytical Solutions. He builds systems that reflect how a business actually runs, and spent roughly a decade architecting enterprise data platforms for operations running $10M–$60B in revenue. More about Analytical Ants.