Skip to content
CompletedWeb

Business Energy Quote Funnel

A six-step lead funnel that works without JavaScript and finds a UK street from a postcode without any paid API.

Six-step formAttributionPOST /api/leadsGET /api/addressesLead logStreet index
Role
Designer & engineer
Team
Solo
Timeline
Sep 2026
Organisation
Green Compare Ltd
Code
Proprietary (employer)
Reading time
2 min

A zero-dependency landing page and Node server for business-energy quotes, with progressive enhancement, ad attribution, spam protection and an offline postcode-to-street index built from open data.

Overview

Business owners comparing energy prices want a quote, not a form marathon. The funnel asks one question per screen — postcode and address, energy type, current supplier, monthly spend, contract end date, contact details — and posts the lead to a tiny server.

The problem

  • Address lookup APIs charge per request and need keys.
  • Paid traffic must be attributed correctly (UTM parameters and click IDs).
  • Forms must still work on old browsers and with JavaScript blocked.

Context & constraints

The page had to be host-agnostic — deployable anywhere — and easy to hand to a CRM later.

Approach

  • Progressive enhancement: with JavaScript off, the form posts normally and the server answers with a redirect; with it on, steps animate and validate inline.
  • Offline street index: a Python preprocessing script turns the OS Open Names dataset into one gzipped file per postcode district — a grid spatial join with 250 m cells, a 200 m search radius and a 600 m rural fallback. An optional premium API can return full premises.
  • Server hygiene: a field allow-list, required-field checks (422), a 50 KB body cap (413), a honeypot that returns a fake success, a path-traversal guard and nosniff.
  • Attribution: UTM parameters and click IDs are captured and pushed as a generate_lead event.
  • A thank-you page knows UK calling hours and says "we're calling you now" only when that's true.

Key capabilities

  • One question per screen, six steps
  • Works without JavaScript
  • Offline postcode → street lookup
  • Honeypot spam protection
  • UTM and click-ID attribution
  • Calling-hours aware confirmation

Architecture

  1. Browser

  2. Node server (no dependencies)

  3. Data

Static front end, a ~300-line Node server with no dependencies, and a preprocessed open-data index. Select a component to trace its connections.

Key decisions

Quality & delivery

Deployment

One node server.js process; a quick tunnel script shares a local build for review.

Outcome

Runtime dependencies
0
Node standard library only
Postcode district files
2,864
Built from OS Open Names

A host-agnostic funnel ready to point at the CRM, with lead capture working end to end.

Lessons

  • The cheapest API call is the one you precomputed.

Building something similar?

Tell me what you’re working on — I reply to every serious message.

Related work

React 19 SPAIdentity providerAPI routers18 domain modulesCapability matrixJob workerTransactional outb…PostgreSQL 16RedisObject storage
Case study
In production2026Green Compare Ltd (XEOO team)

Green Compare CRM

A FastAPI modular monolith with a React 19 front end, where Postgres row-level security backs every permission check. I started the repository, then shipped features across finance, telesales, renewals, dashboards and access control.

  • TypeScript
  • Python
  • React
  • Ant Design
  • TanStack Query
  • FastAPI
  • +9