Leap.new integration rules
This page is the detailed rule set referenced by the Leap.new starter prompt. It exists so the prompt you paste into the builder can stay short — the agent fetches this page and follows the rules below. It is intentionally kept out of the sidebar.
Leap.new builds Encore.ts apps with a React frontend, so use the @ideal-postcodes/react component. It renders its own <input>, attaches the widget, and hands the selected address back through onAddressRetrieved — no useEffect, useRef, CSS selectors, or controlled/uncontrolled juggling. The one thing left to get right is delivering the API key from an Encore secret to the browser. The rules below cover both.
Install the package
- Install
@ideal-postcodes/reactin the frontend. It pulls in@ideal-postcodes/address-finderautomatically; you don't need to add it separately.
Wiring the widget
-
Render the component and read the resolved address from
onAddressRetrieved:import { AddressFinder } from "@ideal-postcodes/react";<AddressFinderapiKey={apiKey}onAddressRetrieved={(address) => {setForm({line_1: address.line_1,line_2: address.line_2,line_3: address.line_3,post_town: address.post_town,postcode: address.postcode,country: address.country,});}}/> -
The component draws its own search
<input>. To reuse a styled input, pass it as a single child instead (wrap mode):<AddressFinder apiKey={apiKey} ...><input className="..." /></AddressFinder>. -
Populate every other field from the
onAddressRetrievedcallback into React state. Those fields are controlled (value+onChange) as normal — the component never writes to them directly. -
After populating fields from the callback, trigger their validation (e.g. set state, then run your existing validators) so a selected address clears any "required" errors.
-
The stylesheet is auto-injected by default (
injectStyledefaults totrue), so the dropdown is styled out of the box. No separate CSS import is required.
API key
The Ideal Postcodes API key is a publishable browser key — it is designed to ship in client-side code and is protected by Allowed URLs, not by secrecy (exactly like a Stripe pk_ publishable key). The component runs in the browser, so the key has to reach client code:
- Add a tiny Encore endpoint that reads
secret("IDEAL_POSTCODES_API_KEY")and returns it to the frontend, e.g.GET /config/ideal-postcodes-api-key. - Fetch that endpoint once on mount and store the key in state. Render
<AddressFinder>only once the key has arrived (render nothing, or a disabled input, until then) and pass it as theapiKeyprop. - Do not hardcode the key in the component.
Errors
- Pass
onSearchErrorandonSuggestionErrorprops. If the Ideal Postcodes API returns a 4xx error, surface the error's message to the user — do not swallow it. A401almost always means the app's origin is missing from the key's Allowed URLs.