In short

A calculator turns a passive visitor into a qualified lead by handing them a real answer to a money question, then asking for their details to send the full result. On ampy.se it is the highest intent lead source on the site, because someone who has just modelled their own payback is already deciding, not browsing. This guide shows how to build one that captures those leads and still ranks on Google, using a small data layer, one honest function, a REST endpoint, a server-rendered fallback, and instant capture.

A contact form asks a stranger to trust you before you have proven anything. A calculator does the opposite. It gives the visitor something useful first, a real number about their own situation, and earns the right to ask who they are. That one reversal is why, on ampy.se, the calculators quietly out-convert every other path on the site. Someone who has just watched a tool work out their own savings is no longer window shopping. They are deciding.

There is a catch that trips most people up. A calculator built the easy way, as one lump of JavaScript, is invisible to Google. The page looks empty to a crawler, so it never ranks, so the tool that converts best gets the least traffic. This guide shows how to build a calculator that captures the lead the moment it becomes valuable and stays fully indexable at the same time. Every outcome you actually care about, more qualified enquiries, a lower cost per lead, and traffic that compounds in search, comes from getting those two things to live together.

Why a calculator earns the lead

A form is a toll gate. It stops the visitor and demands payment, their name and number, before anything of value has changed hands. Most people walk away. A calculator flips the order. It does the work first, shows a result that is obviously about them, and only then offers to email the full breakdown. By the time it asks, the visitor wants the answer more than they mind giving an email address.

A visitor who has just modelled their own payback is not a lead you have to chase. They are a lead who is now chasing you.

This is why the intent is so high. The person did not stumble in. They typed numbers about their own home, watched a tool respond, and reached the edge of a decision. When a senior electrician calls them back, the conversation starts halfway to done.

What we are building

Strip away the topic and every good calculator is the same four parts. Get these right once and you can build the next one in an afternoon.

  1. A data layer that holds the numbers the maths depends on, kept out of the code so a rate change is a one line edit.
  2. A calculation function, the actual logic, with one clear input and one clear result.
  3. A small REST endpoint the front end can call, paired with a server-rendered fallback so the page is never empty.
  4. A capture step that fires the instant the result is worth something, straight to a human.

On ampy.se this exact shape backs a whole suite: a battery-storage calculator, an EV-charging savings calculator, a panel checker, a job-authority checker, and an LED-lighting calculator. Different maths, identical bones. I will use the battery one here because the numbers are the easiest to follow.

Step one: keep the maths as data, not code

The single biggest mistake is to bury a rate or a price deep inside the calculation. Tax incentives change. Energy prices move. When they do, you do not want to hunt through five calculators looking for the number. You want to edit one line.

Read the moving numbers from one place

Put anything that policy or pricing can change into config, well away from the logic. On ampy.se the Grön Teknik deduction is a government rate, so it lives as a constant, not a magic number sprinkled through the code.

<?php
// wp-config.php: values that policy or pricing can change, kept in one place.
define( 'AMPY_GRON_TEKNIK_RATE', 0.50 );   // 50% deduction on battery + charger
define( 'AMPY_PRICE_PER_KWH', 1.20 );      // placeholder, your real tariff goes here

Why this pays off later

The day the deduction changes, every calculator on the site updates from that one edit. No redeploy of logic, no risk of one tool quoting an old rate while another quotes the new one. The numbers stay honest because there is only ever one copy of them.

Pro tip

Never hard-code a rate that a government can change. The Grön Teknik deduction is set by policy, not by you. Keep it in one constant, and the day it moves you edit a single line instead of auditing twenty calculators for a stale number.

Step two: the calculation is one honest function

The logic itself should be boring. One function, a clear set of inputs in, a clear result out, and nothing else. Boring means testable, and testable means you can trust the number you are putting in front of a customer.

One input, one result

<?php
/**
 * Work out battery sizing and payback from one set of inputs.
 * Pure function: the same input always gives the same result, easy to test.
 */
function ampy_battery_payback( array $in ) {
    $usage_kwh   = max( 0, (float) $in['yearly_kwh'] );
    $system_cost = max( 0, (float) $in['system_cost'] );

    $deduction = $system_cost * AMPY_GRON_TEKNIK_RATE;
    $net_cost  = $system_cost - $deduction;

    // Rough yearly saving from storing cheap power and using it at peak.
    $yearly_saving = $usage_kwh * 0.30 * AMPY_PRICE_PER_KWH;
    $payback_years = $yearly_saving > 0 ? $net_cost / $yearly_saving : 0;

    return array(
        'deduction'     => round( $deduction ),
        'net_cost'      => round( $net_cost ),
        'yearly_saving' => round( $yearly_saving ),
        'payback_years' => round( $payback_years, 1 ),
    );
}

Notice there is no HTML in here, no request handling, no email. It only does the maths. That is deliberate. Because the logic is isolated, you can call it from a web request, from a scheduled job, or from a test, and it behaves the same every time.

Step three: expose it, and never ship an empty page

Now the front end needs a way to ask for a result. A small REST endpoint does the job. It takes the inputs, cleans them, runs the function, and hands back the numbers.

<?php
add_action( 'rest_api_init', function () {
    register_rest_route( 'ampy/v1', '/battery', array(
        'methods'             => 'POST',
        'permission_callback' => '__return_true', // public tool, no login needed
        'args'                => array(
            'yearly_kwh'  => array( 'sanitize_callback' => 'absint' ),
            'system_cost' => array( 'sanitize_callback' => 'absint' ),
        ),
        'callback' => function ( WP_REST_Request $req ) {
            return rest_ensure_response( ampy_battery_payback( array(
                'yearly_kwh'  => $req->get_param( 'yearly_kwh' ),
                'system_cost' => $req->get_param( 'system_cost' ),
            ) ) );
        },
    ) );
} );

The part that keeps you in Google

Here is where most calculators quietly fail. If the result only ever appears after JavaScript runs, a search crawler sees a blank box. The page has no content to rank, so the tool that converts best on your whole site gets buried on page four.

The fix is small. On first load, render a sensible default result straight into the HTML on the server. The visitor still gets the live, interactive version once JavaScript takes over, but the crawler, and anyone with a slow connection, sees real content immediately.

<?php
// Render a default result server-side so the HTML is never empty.
function ampy_battery_fallback_text() {
    $r = ampy_battery_payback( array( 'yearly_kwh' => 8000, 'system_cost' => 90000 ) );
    return sprintf(
        'Example: on a typical system the deduction is about %s kr, with payback near %s years.',
        number_format( $r['deduction'] ),
        $r['payback_years']
    );
}

The difference this makes is not subtle. It is the line between a tool that ranks and a tool that does not.

Approach Converts visitors Ranks on Google Works without JavaScript
Client-only JavaScript Yes No, the page looks empty No
Server-rendered fallback plus JavaScript Yes Yes, the answer is in the HTML Yes

Step four: capture the lead the moment it is qualified

The visitor has their answer. This is the peak of their intent, and it will not last. Now the tool offers to email the full breakdown, and the moment they accept, two things happen at once.

<?php
// When the visitor asks for the full result, capture the lead in real time.
add_action( 'wp_ajax_nopriv_ampy_battery_lead', function () {
    $email  = sanitize_email( $_POST['email'] ?? '' );
    $result = ampy_battery_payback( array(
        'yearly_kwh'  => absint( $_POST['yearly_kwh'] ?? 0 ),
        'system_cost' => absint( $_POST['system_cost'] ?? 0 ),
    ) );

    // 1. Notify the team instantly. The URL lives in wp-config, never in the repo.
    wp_remote_post( AMPY_LEAD_WEBHOOK_URL, array(
        'body'    => wp_json_encode( array( 'email' => $email, 'result' => $result ) ),
        'headers' => array( 'Content-Type' => 'application/json' ),
    ) );

    // 2. Keep it as owned, first-party data for sales and remarketing.
    wp_insert_post( array(
        'post_type'   => 'ampy_lead',
        'post_status' => 'private',
        'post_title'  => $email,
        'meta_input'  => array( 'calc' => 'battery', 'payback' => $result['payback_years'] ),
    ) );

    wp_send_json_success();
} );

Send it in real time

The webhook fires a notification to a phone straight away, and the record is stored as first-party data you own outright, ready for a follow up or a remarketing audience. No third-party form service holds it hostage. It is yours.

Field note

Why the notification has to be instant

Early on it was tempting to collect the calculator leads into a tidy daily digest. That would have been a slow, expensive mistake. A homeowner who has just modelled their battery payback sits at the top of their intent for maybe an hour, and then life takes over again.

So the capture fires the moment it happens, straight to a phone, and a senior electrician can call back while the calculator is still open in the other tab. The maths did the convincing. The speed is what closes the gap before it cools.

What this does for the business

Put the four parts together and you have a tool that does real work, in four ways that all land on the bottom line.

  • It answers a question the customer was already asking, which builds trust before a single sales word is spoken.
  • It captures a lead at the exact peak of intent, which lifts the odds of turning an enquiry into a booking.
  • It stays indexable, so it keeps pulling new people in from search month after month for no extra spend.
  • It hands you owned, first-party data instead of renting it from a form service you do not control.

That is the whole point. The calculator is not a gimmick on the page. It is the part of the site that turns curiosity into a qualified enquiry, and then keeps doing it while you sleep. Build it once, keep the maths honest, keep the page readable to Google, and it becomes the quietest, hardest working salesperson you have.