@ideal-postcodes/react
v0.2.1
Published
React components and hooks for Ideal Postcodes address autocomplete
Downloads
275
Readme
@ideal-postcodes/react
React wrapper for @ideal-postcodes/address-finder. UK and international address autocomplete with a single component.
Install
npm install @ideal-postcodes/react@ideal-postcodes/address-finder is pulled in automatically as a dependency. react and react-dom (^18 or ^19) are peer dependencies.
Quick start
Render the component with your API key. It draws its own <input> and hands selected addresses back via onAddressRetrieved.
"use client";
import { useState } from "react";
import { AddressFinder } from "@ideal-postcodes/react";
export default function CheckoutForm() {
const [address, setAddress] = useState<Record<string, string>>({});
return (
<form>
<AddressFinder
apiKey="ak_..."
defaultCountry="GBR"
detectCountry={false}
placeholder="Start typing your address"
onAddressRetrieved={(a) => setAddress(a)}
/>
<input value={address.line_1 ?? ""} readOnly />
<input value={address.post_town ?? ""} readOnly />
<input value={address.postcode ?? ""} readOnly />
</form>
);
}See API key allowed-URLs for client-side key restrictions.
Wrap mode
Pass an <input> (or any single element accepting a ref) as children to keep your existing markup, refs, and styling. Useful with shadcn/ui, MUI, Mantine, or any styled-input setup.
"use client";
import { AddressFinder } from "@ideal-postcodes/react";
import { Input } from "@/components/ui/input"; // shadcn/ui
export function AddressField({ onAddress }: { onAddress: (a: Record<string, string>) => void }) {
return (
<AddressFinder
apiKey="ak_..."
defaultCountry="GBR"
detectCountry={false}
onAddressRetrieved={onAddress}
>
<Input placeholder="Search address" className="w-full" />
</AddressFinder>
);
}In wrap mode the standard HTML input props on <AddressFinder> are ignored - the child owns its own props.
API
<AddressFinder>
| Prop | Required | Notes |
|---|---|---|
| apiKey | yes | Your Ideal Postcodes API key (typically begins ak_). |
| children | no | A single <input> element. Enables wrap mode. |
| inputRef | no | Ref forwarded to the rendered <input> (default mode only). |
Callbacks
All callbacks from the underlying widget are accepted. Semantics are documented under Address Finder callbacks:
onAddressRetrieved, onAddressSelected, onAddressPopulated, onSuggestionsRetrieved, onSuggestionError, onSearchError, onFailedCheck, onCountrySelected, onContextChange, onOpen, onClose, onFocus, onBlur, onInput, onKeyDown, onMouseDown, onSelect, onLoaded, onMounted, onRemove, onUnhide.
Callbacks are read from the latest render, so inline closures are fine - no useCallback needed.
Behavioural options
All behavioural options map 1:1 to the legacy widget options: defaultCountry, restrictCountries, queryOptions, resolveOptions, removeOrganisation, titleizePostTown, checkKey, format, hideToolbar, detectCountry, injectStyle, and all msg* / *Class string overrides.
Standard HTML input props
id, name, className, placeholder, disabled, required, aria-label, aria-describedby, aria-labelledby.
Differences from the vanilla library
React owns the DOM, so DOM-coupled options from the vanilla widget have no React equivalent and are intentionally absent:
| Vanilla option | React idiom |
|---|---|
| inputField | The component attaches to its own <input> (or your children). |
| outputFields, outputScope, scope, names, labels | Read onAddressRetrieved and update your own state/fields. |
| hide, unhide, unhideClass, msgUnhide | Conditionally render fields with React state. |
| inputStyle, listStyle, mainStyle, containerStyle, liStyle | Style via className and CSS. |
| document | The component reads document from its host. |
CSS
Styles are auto-injected by default via injectStyle: true. To opt out and bring your own stylesheet:
<AddressFinder apiKey="ak_..." injectStyle={false} />// Side-effect import (e.g. in your root layout)
import "@ideal-postcodes/react/css/address-finder.min.css";The unminified version is available at @ideal-postcodes/react/css/address-finder.css.
Next.js App Router
The component uses useEffect and event handlers, so it must run in a client component. Either add "use client" at the top of the file that renders <AddressFinder>, or wrap it in a client component. The package ships with "use client" in its built output, but Next.js still requires the consuming file to be a client boundary.
License
SEE LICENSE IN LICENSE
Feedback
Issues and feature requests: ideal-postcodes/feedback.
