Skip to content
AutoSuggesAutoSugges home
Start free
Menu
Appearance
Appearance: System.

Countries autocomplete in Expo

A country field in Expo that stores a stable value, shows the flag the list carries, and finds a country by its code as well as its name.

How do I add a country picker with flags in Expo?

Point the useAutosuggesCombobox hook from the native entry at your countries list key, store item.value from the selection and read item.flag for the flag. The flag comes with the list, so no flag library is needed. Typing a code such as US or USA finds United States, because aliases resolve to the same item.

What is different about countries

The flag travels with the item
Each country carries a flag, delivered as item.flag. The default row renders it, so a flag icon set is not needed.
Codes are aliases
Typing US or USA finds United States. Aliases resolve to the canonical item at no extra cost.
A flat list
Countries have no hierarchy, so there are no ancestors to fill and no parent filter. A parent on a non-hierarchical list is refused as an invalid request.
Store the value, show the label
Store item.value. Show item.displayValue, which is resolved for the requested locale when the list is published.

Steps

  1. Publish or subscribe to the countries dataset and create a publishable key for the application.
  2. Create the client once and call bootstrap() so the real minimum length and debounce are used.
  3. In the selection handler, store item.value and read item.flag if you show the flag elsewhere in the form.
  4. Keep the flag decorative: hide it from assistive technology, because the country name already says it.

Code

import { useEffect } from 'react';
import { AccessibilityInfo, FlatList, Pressable, Text, TextInput } from 'react-native';
import { createAutosuggesClient } from '@autosugges/client';
import {
  activeOptionAnnouncement,
  getInputAccessibilityProps,
  getListAccessibilityProps,
  getOptionAccessibilityProps,
  handleNativeKeyPress,
  useAutosuggesCombobox,
} from '@autosugges/client/native';

const autosugges = createAutosuggesClient({
  baseUrl: 'YOUR_RUNTIME_BASE_URL',
  publishableKey: 'YOUR_PUBLISHABLE_KEY', // the key for your countries list
});
void autosugges.bootstrap().catch(() => {});

export function CountryField({ onChange }: { onChange: (country: string) => void }) {
  const combobox = useAutosuggesCombobox({
    source: autosugges,
    onSelect: (item) => onChange(item.value),
  });
  const { state } = combobox;

  const spoken = activeOptionAnnouncement(state);
  useEffect(() => {
    if (spoken !== undefined) AccessibilityInfo.announceForAccessibility(spoken);
  }, [spoken]);

  return (
    <>
      <TextInput
        {...getInputAccessibilityProps(state)}
        accessibilityLabel="Country"
        value={state.inputValue}
        onChangeText={combobox.setInputValue}
        onKeyPress={(event) => handleNativeKeyPress(combobox, event.nativeEvent.key)}
      />
      <FlatList
        {...getListAccessibilityProps()}
        data={state.items}
        keyExtractor={(item) => item.itemId}
        renderItem={({ item, index }) => (
          <Pressable
            {...getOptionAccessibilityProps(state, index)}
            accessible
            onPress={() => combobox.selectIndex(index)}
          >
            <Text>
              <Text accessibilityElementsHidden importantForAccessibility="no-hide-descendants">
                {item.flag}{' '}
              </Text>
              {item.displayValue}
            </Text>
          </Pressable>
        )}
      />
    </>
  );
}

The publishable key is public by design and safe in client code. A secret key never belongs here.

Check that it works

  1. Type US. United States appears, with its flag.
  2. Type uni and then pick a country. The stored value is the country, not the text you typed.

Frequently asked questions

Do I need a flag library for the country picker?
No. Each country in the list carries its flag, and the component shows it in the row. Read item.flag when you want to show it elsewhere in your form.
Can people type a country code instead of the name?
Yes. The two-letter and three-letter codes are aliases of each country, so typing US or USA finds United States. Aliases are part of the list and cost nothing extra at query time.
Which value should I save?
Save item.value, which is stable. item.displayValue is the label for the requested locale and can differ between locales, so it is for showing rather than storing.
What is the minimum number of characters before a query runs?
Two by default. A list owner can change the minimum, but it can never be 1. The client reads the real value from bootstrap and sends no request below it, so do not hardcode it.
Where does the publishable key go?
In the key query parameter of the request, for example /v1/query?key=YOUR_PUBLISHABLE_KEY, never in a header. The key is public by design and safe in client code. Secret keys never belong in a browser or mobile bundle, and a proxy to hide the publishable key is unnecessary.