Skip to main content
Upcoming — generated from the latest merged element source; documents unreleased development. Use the channel picker at the top of the sidebar for the docs of a published release.
In development — not yet part of a stable release. Belongs to the Payments group. Render <AddressElement /> inside it (React), or call payments.create('address', { … }) on the handle (vanilla) — consumer props and on<Event> callbacks both go in the create options / JSX props.

Preview

A live, interactive demo of this element with sample data:

Usage

Props

"full" | "compact"
full (default) stacks labeled fields; compact fuses them into one dense bordered group with placeholder labels. Defaults to "full".
"split" | "combined" | "none"
The name row: one full-name field (default), split first/last fields, or none. Defaults to "combined".
"never" | "toggle" | "always"
Address line 2: always visible (default), revealed by a text button (toggle), or never collected. Defaults to "always".
"billing" | "shipping"
Which autocomplete family the fields advertise to the browser: billing (default) or shipping. Defaults to "billing".
"full" | "minimal"
full (default) collects the country’s complete address format; minimal collects the AVS floor of ADDRESS fields only — country plus postal code. The name row is governed by the name prop independently of scope, and a rendered name row is required (set name: 'none' for a pure country+postal collection). Note: the standalone element never widens to a payment method’s own declared billing floor — a card confirm requires the cardholder name, country, and postal code, so beside a card method keep name enabled or pass it in the confirm’s billingDetails. Defaults to "full".
"name" | "none" | "name_with_type"
The organization row: hidden (default), a name field, or a name field plus a business/individual type select. Defaults to "none".
{ name?: string | undefined; address?: { name?: string | undefined; first_name?: string | undefined; last_name?: string | undefined; organization?: string | undefined; organization_type?: "business" | "individual" | undefined; line1?: string | undefined; line2?: string | undefined; city?: string | undefined; state?: string | undefined; postal_code?: string | undefined; country?: string | undefined; } | undefined; }
Seed values applied once before first paint (address.country is ISO2). Takes precedence over IP-country detection.
boolean
Default the country from the buyer’s IP (resolved before first paint). Falls back to the controller’s countryHint, then US. Defaults to true.
string[]
Restrict the country select to these ISO2 codes. A single entry locks the country — the select stays openable and shows the one choice.
boolean
Google Places suggestions on the street-address field. When Places is unavailable (no key, blocked loader) the field is a plain input. Defaults to true.
({ key: string; label: string; type: "text" | "select" | "date" | "phone"; position: "after_name" | "after_organization" | "before_country" | "after_address"; required?: boolean | undefined; options?: string[] | undefined; format?: string | undefined; autocomplete?: string | undefined; })[]
Extra fields rendered inline with the same chrome: { key, label, type: text|select|date|phone, position: after_name|after_organization|before_country|after_address, required?, options?, format?, autocomplete? }. Values are validated centrally and emitted under the separate custom bag.
string
Optional ISO2 fallback for the country-detect chain (defaultValues > IP country > this > US) — e.g. derived from a checkout currency when it maps to exactly one country. Empty (default) = no hint. (When the payments controller later declares this element, its currency-derived hint wants to layer over this — the framework has no controller-OR-consumer prop source yet, so that wiring lands with that chunk.) Defaults to "".

Events

Pass a callback in the create options (or React prop) to receive these.

onChange

The address changed — complete: true means every required field for the selected country (plus any required custom fields) is filled and valid. address uses the confirmation-token billing_details naming (postal_code, ISO2 country); custom field values ride the separate custom bag. Signature: ((payload: { complete: boolean; address: { name?: string | undefined; first_name?: string | undefined; last_name?: string | undefined; organization?: string | undefined; organization_type?: "business" | "individual" | undefined; line1?: string | undefined; line2?: string | undefined; city?: string | undefined; state?: string | undefined; postal_code?: string | undefined; country: string; }; custom: Record<string, string>; }) => void)

onLoaderStart

Fired the moment the element’s own loading skeleton has painted inside its frame — the earliest point a consumer-managed loading state can hand off without ever exposing a blank. Always precedes onReady; most consumers only need onReady. Signature: (() => void)

onReady

Fired once the element has booted and painted its first complete frame. Signature: (() => void)

onError

Fired when the element fails to load or crashes; the element shows its own error fallback. message is human-readable; framework refusals also carry code (e.g. HOST_SOURCE_FAILED, with sourceKey naming the failed hostState key) so hosts can switch on codes, never message text. Signature: ((e: { message: string; code?: string | undefined; sourceKey?: string | undefined; }) => void)

Methods

Call these on the element handle — the return of create (vanilla) or the component ref (React).

validate

Validate the whole form, revealing every error inline. Resolves { complete, address, errors } — never throws; errors is empty exactly when complete is true. Error keys are the contract field keys (postal_code, line1, …), custom:<key> for custom fields, and the transient form key returned while the form is still loading. Signature: () => Promise<{ complete: boolean; address: { name?: string | undefined; first_name?: string | undefined; last_name?: string | undefined; organization?: string | undefined; organization_type?: "business" | "individual" | undefined; line1?: string | undefined; line2?: string | undefined; city?: string | undefined; state?: string | undefined; postal_code?: string | undefined; country: string; }; errors: Record<string, string>; }>

getValues

Read the current values without validating or revealing errors: { address, custom }. Signature: () => Promise<{ address: { name?: string | undefined; first_name?: string | undefined; last_name?: string | undefined; organization?: string | undefined; organization_type?: "business" | "individual" | undefined; line1?: string | undefined; line2?: string | undefined; city?: string | undefined; state?: string | undefined; postal_code?: string | undefined; country: string; }; custom: Record<string, string>; }>

mount

Place the element on the page: appends its container to target (a CSS selector or an element) and starts loading. Nothing renders until this is called. React consumers never call it — the component mounts itself. Signature: (target: string | HTMLElement) => void

destroy

Remove the element from the page and release its frame and subscriptions. Safe to call more than once. React consumers never call it — unmounting the component does it. Signature: () => void

update

Change this element’s consumer props after mount — it re-renders with the merged props. React consumers never call it — updating the JSX props does the same. Signature: (options: Partial<AddressElementProps>) => void

Styling

Each part below is a stable class name — safe to depend on. Restyle a part by mapping its class to a style declaration object under appearance.classes (properties camelCase or kebab-case, values as strings with units — the same shape as React’s style prop). The element renders in its own frame, so page stylesheets can’t reach it: these declarations are sanitized against a safe-property allowlist and injected inside the frame for you.
In React, pass the same object as the appearance prop on <Payments>; appearance also applies globally at WhopElements({ appearance }).