An address form is one of the first things you'd call simple. Street, city, state, ZIP.
Most address forms are a US address form with a country dropdown on top. A shopper in London has no state to pick. A shopper in Berlin writes the postal code before the city. A shopper in Tokyo starts from the other end entirely.
When I built the Address Form block for HextaUI, it had to handle 16 countries. Change the country below.
The country decides everything
The country isn't one more field. It decides which fields exist, what they're called, which are required and what order they go in.
| Country | After the street | Region | Postal code |
|---|---|---|---|
| United States | City, State, ZIP | Required | 12345 |
| United Kingdom | Town or city, Postcode | None | SW1A 1AA |
| Germany | Postal code, City | None | 5 digits |
| Japan | Postal code, Prefecture, City | Required | 123-4567 |
| Canada | City, Province, Postal code | Required | K1A 0B1 |
So the form never mentions a country by name. It only renders rows from data.
const JP = {
rows: [["postalCode", "region"], ["city"]],
localityFirst: true,
required: ["postalCode", "region", "city"],
labels: {
city: "City, ward or town",
region: "Prefecture",
},
postal: { pattern: /^\d{3}-?\d{4}$/, example: "100-0001" },
};
That's a shortened version of the real entry. localityFirst is the big one for Japan, because the street comes after the area. Each entry also holds a phone format, how to print the address, and other names for the country, so a search for 日本 finds Japan.
Details that only show up in real use
Autofill does most of the work. Browsers can fill the whole form in one tap, if every input has the right token. shipping address-level2 means city. address-level1 means state or region. This is the highest-value part of the whole form, and you never see it.
Don't throw away what they typed. People choose a country after typing, or change it by mistake. Fields that exist in both countries should keep their values.
Validate gently. Check the postal code format for countries you know, but don't invent rules for the rest. A wrong validation rule is worse than none, because it stops a real person from giving you a real address and they have no way around it.
Have a plain fallback. I can't cover every country by hand, and I shouldn't pretend to. Everywhere else gets two address lines, city, region and postal code, with none strictly validated.
- US
- CA
- GB
- IE
- DE
- FR
- NL
- ES
- IT
- JP
- IN
- AU
- NZ
- SG
- BR
- MX
This one is personal for me
If you live outside the US, you've probably met a form that was sure you had a ZIP code and a state from a fixed American list. The form is telling you, politely, that nobody thought of you.
That's what makes a form like this worth the work. It's the longest form in most stores, and it comes right before someone pays you. A person who has to fight it might just leave.
If you're building one, read Google's address metadata from libaddressinput before you write any rules yourself. Most of this is already written down.