Como construir um formulário de endereço que funcione em todos os países, em React
Um formulário de endereço americano com um dropdown de país não é internacional. Campos por país, códigos postais, tokens de autofill, busca de endereço e erros em React.
Preet Suthar · · 6 min de leitura
- React
- Forms
- E-commerce
- Accessibility
A maioria dos formulários de endereço é um formulário de endereço americano com um dropdown de país em cima. Cidade, estado, ZIP code, nessa ordem, para todo mundo. Aí um cliente em Londres não tem estado para escolher, um cliente em Berlim digita o código postal antes da cidade por hábito, e um cliente em Tóquio precisa escrever o endereço de trás para a frente.
Um formulário de endereço é o formulário mais longo que a maioria das lojas tem, e é onde preenchimento automático, validação e usuários internacionais se encontram. É assim que se constrói um em React que funcione em todos os países para onde você envia.
Primeiro o país, depois o layout
O país decide quais campos existem, como se chamam, quais são obrigatórios e em que ordem aparecem. Então peça o país primeiro, pré-selecionado a partir do locale ou do IP do cliente, e monte o resto a partir de dados.
Alguns exemplos do quanto as coisas mudam:
| País | Campos depois da rua | Região | Código postal |
|---|---|---|---|
| Estados Unidos | Cidade, estado, ZIP code | Obrigatório | 12345 ou 12345-6789 |
| Reino Unido | Cidade, postcode | Nenhum | Como SW1A 1AA |
| Alemanha | Código postal, cidade | Nenhum | 5 dígitos |
| Japão | Código postal, província, cidade | Obrigatório | 123-4567 |
| Canadá | Cidade, província, código postal | Obrigatório | Como K1A 0B1 |
Você não precisa pesquisar cada país na mão. O Google publica os metadados de endereço por trás da biblioteca libaddressinput, com ordem dos campos, rótulos, campos obrigatórios e padrões de código postal para a maior parte do mundo. Escolha os países para onde você mais envia e dê a eles um formato exato, e dê a todos os outros um fallback simples: duas linhas de endereço, cidade, região e código postal, nenhum validado de forma rígida.
O componente do formulário então renderiza format.rows e nunca menciona um país pelo nome.
Menos campos
Cada campo que você mostra é mais uma coisa para preencher e mais uma coisa para errar.
- Um só campo de nome. "Nome completo", não nome e sobrenome. Muitos nomes não se dividem em duas partes, e a ordem muda de um país para outro.
- Linha 2 atrás de um link. "Adicionar apartamento, sala etc." abre o campo. A maioria das pessoas não precisa dele. Se o preenchimento automático ou a busca de endereço preencher o campo, mostre-o.
- Empresa também atrás de um link, para os poucos pedidos B2B.
- Telefone opcional, com o motivo. "Só para dúvidas sobre a entrega" abaixo do campo rende mais números do que um campo obrigatório rende números de verdade.
O preenchimento automático faz a maior parte do trabalho
O preenchimento automático do navegador consegue preencher o formulário inteiro com um toque, mas só se cada input tiver um name e o token de autocomplete certo. Prefixe os tokens com shipping ou billing para que o navegador saiba qual endereço salvo vai para onde:
address-level1 é o estado, a província ou a província japonesa, e address-level2 é a cidade. Quando o endereço de cobrança for diferente do de entrega, renderize um segundo formulário com tokens billing, para que o navegador não preencha o formulário de cobrança com o endereço de entrega.
Não use type="number" para códigos postais. ZIP codes começam com zeros, os códigos do Reino Unido e do Canadá têm letras, e inputs numéricos vêm com spinners e mudam de valor com a rodinha do mouse. Use um input de texto com inputMode="numeric" só onde os códigos são apenas dígitos.
Busca por código postal
Em alguns países, o código postal já diz a cidade e a região. O Japão é o caso clássico: os endereços começam pelo código postal, e o código sozinho identifica a província e a cidade. Quando o cliente terminar de digitar o código postal, consulte-o e preencha cidade e região, mas nunca sobrescreva algo que ele já digitou. O que ele digitou vale mais que os seus dados.
Busca de endereço
A busca de endereço, digitar o começo de um endereço e escolher uma sugestão, é mais rápida que qualquer formulário no celular. Google Places e Mapbox oferecem isso como duas chamadas: uma que sugere endereços para o que foi digitado e outra que transforma a sugestão escolhida em campos estruturados.
Algumas regras para conectar tudo:
- Espere uma pausa na digitação e cancele a requisição anterior, como em qualquer campo de busca.
- Sempre termine a lista com "Inserir endereço manualmente". A rua pode ser nova, ou a sugestão pode estar errada.
- Depois da escolha, preencha os campos e mostre-os, para que o cliente possa conferir o resultado e adicionar o número do apartamento.
- A Places API do Google usa tokens de sessão para agrupar as chamadas de sugestão e de detalhes de uma mesma busca. Use-os, ou as chamadas podem ser cobradas separadamente.
Erros que dizem o que está errado
Valide um campo quando o cliente sair dele e depois ao vivo enquanto ele digita, até estar corrigido. Escreva o erro para o país: "Digite um ZIP code de 5 dígitos" nos EUA, "Digite um postcode como SW1A 1AA" no Reino Unido. "Código postal inválido" não ajuda ninguém.
Ao enviar, liste todos os problemas num resumo no topo do formulário, ligue cada um ao seu campo e mova o foco para o resumo. Conecte cada erro ao seu input com aria-describedby e defina aria-invalid, para que os leitores de tela leiam a mensagem junto com o campo.
Normalize antes de validar: remova espaços, coloque em maiúsculas os códigos postais do Reino Unido e do Canadá e aceite-os com ou sem o espaço. Rejeitar "sw1a1aa" quando você poderia corrigir é um bug seu, não do cliente.
Trocando de país
As pessoas mudam o país depois de digitar metade do endereço com mais frequência do que você imagina. Quando isso acontecer, mantenha o que ainda serve (nome, linhas de rua, telefone), limpe a região se o novo país tiver outra lista e revalide só os campos que elas já tocaram. Mostrar erros novos em campos a que a pessoa ainda nem chegou parece uma bronca por algo que ela não fez.
Armazene a estrutura, não a string
Salve o endereço como campos mais um código de país ISO, não como linhas formatadas. Você vai precisar da estrutura para impostos, fretes e etiquetas de transportadora, e sempre dá para formatar para exibição. Um resumo de uma linha como "12 Mission St, San Francisco, CA 94110" é uma visualização dos dados, não os dados.
Um checklist
- País primeiro, depois campos, rótulos e ordem a partir de um formato por país.
- Um formato exato para os seus países principais e um fallback tolerante para o resto.
- Um só campo de nome, linha 2 e empresa atrás de links, telefone opcional com um motivo.
- Um
namee um token de autocompleteshippingoubillingem cada input. - Inputs de texto para códigos postais, teclado numérico só onde os códigos são dígitos.
- Busca por código postal que nunca sobrescreve valores digitados.
- Busca de endereço com uma opção de preenchimento manual no fim.
- Textos de erro específicos por país e um resumo com links ao enviar.
O bloco do HextaUI para isso
O bloco Address Form do HextaUI Pro é construído sobre essas regras. Dezesseis países têm o próprio formato, com rótulos, campos obrigatórios, listas de regiões e regras de código postal, e todos os outros países recebem um fallback simples. Cada input tem o token de autocomplete certo com prefixo shipping ou billing. onSearchAddress e onResolveAddress conectam a busca de endereço, com um exemplo para Google Places, e as mesmas duas chamadas se encaixam no Mapbox. onLookupPostalCode preenche cidade e região sem sobrescrever nada que foi digitado, e validate() lista todos os problemas num resumo com links. SavedAddresses e AddressSummary cobrem clientes logados e a linha "Enviar para" já concluída.
O bloco Checkout usa ele para a entrega. Se você está construindo o resto dessa página, também escrevi sobre um checkout de uma página em React e Next.js.
FAQ
O campo de país deve vir primeiro? Sim. Ele decide quais campos existem e em que ordem aparecem, então precisa ser escolhido antes que o resto faça sentido.
Devo usar campos de nome e sobrenome? Use um único campo de nome completo, a menos que uma transportadora ou um provedor de pagamento exija a divisão.
Que tipo de input um código postal deve usar? Um input de texto, com inputMode="numeric" só para países cujos códigos são todos dígitos.
Preciso de validação de endereço por API? Ajuda, mas não bloqueie o pedido por causa dela. Sugira uma correção e deixe o cliente manter o que digitou.