Skip to content
All builds
Websites

ThresholdLead Capture + Thank-You Flow

What it does for you

A contact form that asks the right questions and puts serious leads first.

Multi-step lead capture with branching, scoring, bot checks, and UTM capture, ending on a thank-you screen that qualifies the visitor and offers the next step, exportable as a one-script embed.

Threshold screenshot

Who it's for

Any small business that gets inquiries through a website form and wants to know which ones deserve a call first. You write the questions yourself and can see which one makes people give up.

Screenshots

Threshold screenshot 1

In more detail

Threshold is a signup form that asks one question at a time and adapts to your answers. When you finish, the thank-you page tells you what you qualified for, what happens next, and how to book a call. Behind it sit a form builder, a leads table, and a funnel view that shows which question is costing leads.

Honest limits

No retry queue for webhooks, so a failed POST is just lost. Leads, progress, and events live in localStorage. It is not AI-powered. The flow was checked with scripted runs and headless screenshots, not with real visitors. It works and it is tested, but it is not hammered.

How I built it

One of the parallel Claude Code builders from the September 19 one-shot night. My direction was short: one config drives everything, the thank-you screen has to do real work (qualify, set expectations, offer a next step), and the export has to be a paste-anywhere snippet. Claude Code wrote the core module (flow.js), the runtime, the builder UI, and 154 assertions.

The first session got cut off after the app, tests, server, and screenshots were done but before any write-up existed. A second session re-ran the suite, confirmed both themes rendered in demo mode, checked fonts and the no-em-dash rule, and wrote the docs. I accepted two assumptions to stay inside the box: webhook delivery is a plain JSON POST with no retry, and the calendar button links out instead of embedding a scheduler. Logged time was about half an hour.

What I learned

  • Branching forms need "effective answers", not raw answers. If someone goes back and changes the answer that revealed a step, the old value is still sitting in state and can unhide later steps or add score points. We walk the steps in order and only count an answer when its own step is still visible.
  • Step-to-step drop-off is wrong for a branching funnel. If only large companies see the phone step, comparing it to the step before reports people who correctly skipped it as losses. Counting each session as dropped at the furthest step it reached gives numbers I can act on.
  • Function.prototype.toString() works as a bundler for a no-build embed, with rules: every helper is a named function in dependency order, and anything inlined into a script tag gets its closing script sequence escaped.
  • A honeypot should fail silently, but a too-fast-to-be-human check should show a gentle retry, because a quick human can trip it.

What carried forward

The embed snippet is built from the same functions the app imports and the tests run. The tests rebuild that snippet and check it gives the same answers as the module, which is the "shipped code is the tested code" idea from #9 through #11 pushed one step further, all the way into the code a customer pastes. It also used the standard serve.mjs (port 5123) and the brief's ?demo=1 and ?theme= flags for repeatable screenshots. The honeypot lesson lines up with #22, built the same night.

If I took it further

I would add a small local retry queue for webhook delivery and record time spent per step, since a slow step warns you earlier than an abandoned one.

#023 Built with Claude Code September 20, 2026 154 automated checks

Want one like this?