⚛️ OFFICIAL REACT & NEXT.JS SDK

UK Address Autocomplete in React & Next.js

Learn how to use the official @ahm-labs/fast-address-uk SDK to implement sub-15ms UK address lookups, automatic debouncing, race-condition mitigation, and Ordnance Survey UPRN autofill in React checkout forms.

⚡ LIVE REACT HOOK ISLAND

Interactive useFastAddress Hook Tester

This interactive component is powered directly by the @ahm-labs/fast-address-uk/react SDK package running inside this Astro Island.

Quick tests:

Live Hook State Inspector

query:""
isLoading:false
results.length:0
error:null
Active Hook Output
{
  "query": "",
  "isLoading": false,
  "resultsCount": 0,
  "firstResult": null
}

1. Install SDK Package

Terminal
npm install @ahm-labs/fast-address-uk
# or
pnpm add @ahm-labs/fast-address-uk
# or
yarn add @ahm-labs/fast-address-uk

2. Use the useFastAddress Hook

Import useFastAddress from @ahm-labs/fast-address-uk/react:

UkAddressInput.tsx
import React from 'react';
import { useFastAddress } from '@ahm-labs/fast-address-uk/react';

export function UkAddressInput({ onSelect }: { onSelect?: (addr: any) => void }) {
  const { query, results, isLoading, error, search, clear } = useFastAddress({
    debounceMs: 200, // Debounce in milliseconds
    minQueryLength: 2
  });

  return (
    <div className="address-wrapper" style={{ position: 'relative', width: '100%' }}>
      <input
        type="text"
        value={query}
        onChange={(e) => search(e.target.value)}
        placeholder="Enter postcode or street (e.g. SW1A 1AA)..."
        style={{
          width: '100%',
          padding: '12px 16px',
          borderRadius: '8px',
          border: '1px solid #d1d5db',
          fontSize: '15px'
        }}
      />

      {isLoading && (
        <span style={{ position: 'absolute', right: 12, top: 14, fontSize: 12, color: '#6b7280' }}>
          Searching...
        </span>
      )}

      {results.length > 0 && (
        <ul style={{
          position: 'absolute',
          top: '100%',
          left: 0,
          right: 0,
          background: '#ffffff',
          border: '1px solid #e5e7eb',
          borderRadius: '8px',
          marginTop: '4px',
          boxShadow: '0 10px 15px -3px rgba(0,0,0,0.1)',
          maxHeight: '260px',
          overflowY: 'auto',
          listStyle: 'none',
          padding: '4px',
          zIndex: 50
        }}>
          {results.map((item) => (
            <li
              key={item.id || item.uprn}
              onClick={() => {
                onSelect?.(item);
                clear();
              }}
              style={{
                padding: '10px 12px',
                cursor: 'pointer',
                fontSize: '14px',
                borderRadius: '6px',
                borderBottom: '1px solid #f3f4f6'
              }}
            >
              <strong>{item.address_string}</strong>
              <span style={{ display: 'block', fontSize: '12px', color: '#2563eb' }}>
                {item.postcode} • UPRN: {item.uprn || 'N/A'}
              </span>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

3. Connect to Checkout State

Autofill street lines, postal codes, and hidden UPRN fields:

CheckoutForm.tsx
import React, { useState } from 'react';
import { UkAddressInput } from './UkAddressInput';
import type { AddressResult } from '@ahm-labs/fast-address-uk';

export function CheckoutForm() {
  const [formData, setFormData] = useState({
    line1: '',
    postcode: '',
    uprn: '',
    latitude: '',
    longitude: ''
  });

  const handleAddressSelect = (address: AddressResult) => {
    setFormData({
      line1: address.address_string,
      postcode: address.postcode,
      uprn: String(address.uprn || ''),
      latitude: String(address.latitude),
      longitude: String(address.longitude)
    });
  };

  return (
    <form className="checkout-form">
      <label>Search Address / Postcode:</label>
      <UkAddressInput onSelect={handleAddressSelect} />

      <div style={{ marginTop: '16px' }}>
        <label>Address Line 1:</label>
        <input type="text" value={formData.line1} readOnly />
      </div>

      <div style={{ marginTop: '16px' }}>
        <label>Postal Code:</label>
        <input type="text" value={formData.postcode} readOnly />
      </div>

      <input type="hidden" name="uprn" value={formData.uprn} />
    </form>
  );
}

Agentic Discoverability

Building with Cursor, Claude Code, or Windsurf? Our repo includes .agentskills/SKILL.md so AI assistants write optimal implementation code automatically.

View Full REST API Reference →