Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
  1. Home
  2. Blog
  3. Component guides
  4. React Country Select With Flags, Search and Dial Codes
Auf Deutsch lesen
  1. Blog
  2. Component guides
  3. React Country Select With Flags, Search and Dial Codes
Component guides
Component guides

React Country Select With Flags, Search and Dial Codes

SR
Serban Rusu · Founder of Wingo UI
Nov 6, 2026 · 9 min read

On this page

0%
  1. What should a React country select do?
  2. Which React country select packages are there?
  3. How do you build a React country select with flag icons?
  4. How do country names get localized?
  5. Should you store the country name or the ISO code?
  6. How do you show dial codes and pick several countries?
  7. Why do flags show as letters on Windows?
  8. How does it behave on phones and with a keyboard?
  9. When is a phone input or a timezone select the better field?
  10. Which pitfalls show up in production?
  11. How do you install it?
  12. FAQ
    1. How do I make a React country select with flags?
    2. Why do country flag emojis show as two letters on Windows?
    3. Should I store the country name or the country code?
    4. Does shadcn/ui have a country select?
    5. How do I localize country names in React without a translation file?
    6. Is the Wingo UI Country Select free?

TL;DR

A good React country select stores the ISO 3166-1 alpha-2 code (US, DE), shows each country with its flag and its name in the reader's language through Intl.DisplayNames, and searches by name, English name, code, dial code and common short names like UK or USA. Put the likely country on top, submit the code through a hidden native select so autofill works, use a bottom sheet on phones and a code chip where Windows has no flag emoji. The Wingo UI Country Select does all of this, with single or multiple selection.

Published Nov 6, 2026

A React country select looks like the easiest field on a checkout form. Then real users arrive: someone in Munich types "deutschland", someone in London types "UK", a Windows laptop shows "US" where the flag should be, and your database holds "United States", "USA" and "United States of America" for the same customer. This guide covers what the field needs to do, which npm packages exist, and how to use the Wingo UI Country Select for a searchable country dropdown with flags, localized names, dial codes and multiple selection. It also covers when a Phone Input or a Timezone Select is the field you actually want.

What should a React country select do?

Seven things separate a country picker that takes a second from one people scroll through:

  1. Store the ISO code. The value is "US" or "DE". The name is presentation.
  2. Names in the reader's language. A German visitor sees Deutschland, Frankreich and Vereinigte Staaten, sorted the German way.
  3. Search that forgives. Match the localized name, the English name, the ISO code, the dial code (+44) and the short names people type (USA, UK, Holland), with accents ignored, so cote finds Côte d'Ivoire.
  4. The likely country first. A "Suggested" group with the visitor's own country or your top markets, so most people never search.
  5. Flags that render everywhere. Emoji flags are free, except on Windows, which shows letters.
  6. A real form value. A hidden native select with autocomplete="country" so FormData gets the code and browser autofill fills it from a saved address.
  7. A phone layout. About 245 rows in a popover anchored to a 44px field are hard to scroll with a thumb. A bottom sheet with the search pinned on top works better.

Which React country select packages are there?

If you search npm for a react country dropdown with flags, four packages come up, each covering a different part of the job. As of November 6, 2026, from the npm registry and each README:

OptionLatest releaseWhat it gives youNames
react-flags-select (opens in a new tab)2.5.0, Jun 2025a select with SVG flags, search opt-in (searchable)its bundled list, relabel with customLabels
react-select-country-list (opens in a new tab)2.2.3, Jan 2021label and value data for react-selectEnglish
react-country-region-selector (opens in a new tab)4.0.6, Feb 2026connected country and region dropdownsfrom country-region-data
i18n-iso-countries (opens in a new tab)7.14.0, Feb 2025names in many languages, no UIregistered JSON per language
Wingo UI Country Selectcopied sourcesearchable select, flags, dial codes, multiple, phone sheetIntl.DisplayNames

All four npm packages are MIT licensed. The Wingo UI component is part of the paid Pro plan. If you only need flags in a plain dropdown and want a free package, react-flags-select is the most direct fit. If you need regions or states under the country, react-country-region-selector does that and the Wingo UI component does not.

A shadcn country select is not in the official shadcn/ui registry (opens in a new tab), which lists 65 UI components as of November 6, 2026 (it has select, native-select and combobox). Community versions exist; check what each one uses for names and flags before you copy it.

How do you build a React country select with flag icons?

Install it with npx wingo-ui@latest add country-select, then render it with a label, a value and a few priority countries:

tsx
"use client";
import { useState } from "react";
import { CountrySelect } from "@/components/ui/country-select";
export function ShippingCountry() {
const [country, setCountry] = useState("US");
return (
<CountrySelect
label="Country"
description="Where we ship your order."
value={country}
onValueChange={setCountry}
priority={["US", "CA", "MX"]}
required
name="country"
/>
);
}

label, description and error render the shared Field anatomy around the trigger, with the label tied to it and the hint linked through aria-describedby. Without priority, the suggested group holds the country of the locale, so en-US suggests the United States and en-GB the United Kingdom. Pass priority={[]} to drop the group.

Open the list and type "germany", "uk", "+44" or "cote": each finds its country with the matched letters in bold
$ npx wingo-ui@latest add country-select
ProCountry Select docs

To limit the list to the countries you ship to, pass countries={["US", "CA", "MX", "DE", "FR"]}. To remove a few, pass exclude. With eight countries or fewer the search row hides itself (search="auto"); set search="always" or "never" to override that.

How do country names get localized?

Older country packages ship a JSON file of English names, plus one more file per language you register. Browsers already know every country name in every major language through Intl.DisplayNames:

ts
new Intl.DisplayNames(["de-DE"], { type: "region" }).of("DE"); // "Deutschland"
new Intl.DisplayNames(["fr-FR"], { type: "region" }).of("JP"); // "Japon"

The Country Select does this for you. Its locale prop sets the language of the names and the sort order. Without it, the component reads the locale from UIProvider, then from the browser. A German list sorts with a German collator, and the English names stay searchable, so a visitor who types "germany" in a German list still finds Deutschland.

The same helpers are exported for your own UI, such as an order summary:

tsx
import { CountryFlag, getCountryName } from "@/components/ui/country-select";
export function ShipsTo({ code, locale }: { code: string; locale: string }) {
return (
<span className="inline-flex items-center gap-1.5">
<CountryFlag code={code} size="sm" />
{getCountryName(code, locale)}
</span>
);
}

One detail that bites in Next.js: Node and Chrome can ship different ICU data, so a few names differ between server and browser (Hong Kong and Macao are examples), and a server-rendered list of about 245 sorted names can fail hydration. The Country Select renders only the chosen country on the server and builds the full list after hydration, so the markup matches.

Should you store the country name or the ISO code?

Store the code. Names depend on the language and change over time (Turkey is Türkiye in English now), while "TR" stays "TR". Stripe's address country field and most carrier APIs take the ISO 3166-1 alpha-2 code.

With name, the component renders a hidden native select (one hidden input per country with multiple) that submits the code. Its autoComplete defaults to "country", so when the browser fills a saved address, the picker updates too. Validate the code again on the server. libphonenumber-js is already a dependency of the component and exports isSupportedCountry:

ts
// app/checkout/actions.ts
"use server";
import { isSupportedCountry } from "libphonenumber-js";
export async function saveAddress(formData: FormData) {
const country = String(formData.get("country") ?? "").toUpperCase();
if (!isSupportedCountry(country)) throw new Error("Unknown country");
// store "US", show the name in the reader's locale when you render it
}

Then <form action={saveAddress}> around the CountrySelect name="country" is all the wiring a plain form needs.

How do you show dial codes and pick several countries?

For a react country code dropdown, add showDialCode. The calling code (+1, +44) appears at the end of each row and after the chosen name. Dial codes are searchable with or without it.

For "Ships to" or "Markets" fields, add multiple. The value becomes a string[], each pick adds a chip with its flag, and the list stays open while you pick:

tsx
"use client";
import { useState } from "react";
import { CountrySelect } from "@/components/ui/country-select";
export function Markets() {
const [markets, setMarkets] = useState<string[]>(["US", "CA"]);
return (
<CountrySelect
multiple
label="Ships to"
description="Up to 5 countries on the Starter plan."
value={markets}
onValueChange={setMarkets}
maxSelected={5}
showDialCode
clearable
name="markets"
/>
);
}

maxSelected caps the count, display switches between chips, count ("3 selected") and text, maxVisibleChips folds the rest into "+N", and wrap lets chips grow the field onto more lines. The multi mode is built on the Multi-select, and the React multi select guide covers chips, select all and limits in depth.

Pick a few more countries: each adds a chip with its flag and the dial code shows in every row
$ npx wingo-ui@latest add country-select
ProCountry Select docs

Why do flags show as letters on Windows?

An emoji flag is two regional indicator characters: US becomes 🇺🇸. macOS, iOS, Android and most Linux desktops draw them as flags. Windows ships an emoji font without national flags, so Chrome and Edge there draw the two letters (Firefox bundles its own emoji font with flags). On any Windows browser the Country Select swaps the emoji for a small code chip after mount, which reads better than two loose letters and looks the same in every browser. Force one or the other with CountryFlag's fallback prop.

If your design needs real flags on every platform, pass your own SVG set through renderFlag:

tsx
<CountrySelect
label="Country"
renderFlag={(code) => (
<img src={`/flags/${code.toLowerCase()}.svg`} alt="" className="h-3.5 w-5 rounded-[2px] object-cover" />
)}
/>

How does it behave on phones and with a keyboard?

Below 768px the field opens a bottom sheet instead of a popover (responsive, default true). The title comes from the label, the search sits pinned under it, rows are 48px tall, and the list renders only the rows in view once it passes virtualThreshold (100), so scrolling about 245 countries stays smooth. On touch, search="auto" waits for a tap on the search row before it focuses, so the keyboard does not cover half the list the moment the sheet opens. With multiple, a Done button closes the sheet.

On a keyboard, typing a letter on the closed field opens the list with that letter in the search. Enter, Space or ArrowDown open it on the chosen country. Inside, the arrows move, PageUp and PageDown jump, Enter picks, and Escape closes and returns focus to the field.

When is a phone input or a timezone select the better field?

A country select is the right field when the country is the data: a shipping or billing address, a tax residence, the markets a store sells to. Two neighbors often do the job better:

  • You want a phone number. Do not put a country select with dial codes next to a text input. The Phone Input has the country button built in, formats the digits for that country as you type, switches the country when someone pastes +44 7400 123456, and returns one E.164 string. The React phone input guide covers validation.
  • You want a time zone. A country does not tell you the time zone (the United States has several). The Timezone Select searches by city, abbreviation or offset, shows UTC offsets and offers "Use my time zone".
Paste a full number with a + prefix: the flag switches to that country and the field formats the rest
$ npx wingo-ui@latest add phone-input
ProPhone Input docs

On a checkout or sign-up form you often use two of them together: a Country Select in the address and a Phone Input under it, both on the same Field anatomy, so labels, errors and sizes line up. The React form components guide covers that anatomy and the rest of the fields, and the component guides category has the other deep dives.

Which pitfalls show up in production?

  • Saving the display name. You end up mapping "Deutschland" back to DE in a migration. Save the code from day one.
  • Hardcoding en-US. Visitors from other countries search in their own language. Leave locale empty to follow the browser or set it once on UIProvider.
  • A suggested group nobody asked for. If the locale guess is wrong for your audience (an English browser in Germany suggests the US), pass your real top markets to priority.
  • A hand-rolled hidden input. Without a native select that carries autocomplete, autofill fills the street and skips the country. Pass name and let the component render it.
  • A full list for three options. If you deliver to three countries, countries with three codes (or a radio group) beats a searchable list of 245.

How do you install it?

Run npx wingo-ui@latest add country-select. It copies the component with the Select, Multi-select and Field parts it uses and installs libphonenumber-js plus the packages those parts need. The Country Select is part of Wingo UI Pro ($8 a month, $80 a year or $150 once), so sign in first with npx wingo-ui@latest login. The Field and the single Select are free with a free account, if you want to start with a short, fixed list of countries and upgrade later.

Components in this post

  • Country Select

    A searchable country picker with flags, localized names, optional dial codes, a suggested group and single or multiple selection.

    Pro
  • Phone Input

    A React phone number input with a searchable country picker, formatting as you type, validation and one clean E.164 value out.

    Pro
  • Timezone Select

    A searchable time zone picker with live UTC offsets, optional local times, region groups and a one-tap Use my time zone row.

    Pro
  • Field

    A React form field wrapper every control shares: label, hint, animated error and counter, fieldsets, and the box recipe all inputs use.

    Free

FAQ

How do I make a React country select with flags?

Build the list from ISO 3166-1 alpha-2 codes, turn each code into its emoji flag from two regional indicator letters (or render an SVG flag), and get the name from Intl.DisplayNames in the reader's locale. Add a search row, put the likely country first and store the code as the value.

Why do country flag emojis show as two letters on Windows?

Windows ships an emoji font without national flags, so Chrome and Edge on Windows draw the two regional indicator letters instead of the flag (Firefox bundles its own emoji font with flags). Detect Windows and show a small code chip, render SVG flags, or load a flag emoji polyfill font.

Should I store the country name or the country code?

Store the ISO 3166-1 alpha-2 code, such as US or DE. Names change between languages and over time (Turkey became Türkiye), while the code stays stable and is what payment and shipping APIs such as Stripe expect.

Does shadcn/ui have a country select?

No. As of November 6, 2026 the official shadcn/ui registry lists 65 UI components and none of them is a country select, so shadcn projects use a community component or build one on Select or Combobox.

How do I localize country names in React without a translation file?

Use Intl.DisplayNames with type region: new Intl.DisplayNames(["de-DE"], { type: "region" }).of("DE") returns Deutschland. It is built into current browsers and Node, so you do not ship a JSON file of names per language.

Is the Wingo UI Country Select free?

The Country Select, the Phone Input and the Timezone Select are part of Wingo UI Pro. The Field and the Select they build on are free.

Try it in your project

Country Select

Pro

A searchable country picker with flags, localized names, optional dial codes, a suggested group and single or multiple selection.

75 components free, no account needed. Pro from $8 a month.

Open Country Select liveSee pricing
  • Forms
  • Country select
  • Internationalization
  • React

Share

SR

About the author

Serban Rusu

Founder of Wingo UI

Serban Rusu founded Wingo UI. He builds its component library, CLI and MCP server, and writes about React interfaces for phones and AI coding agents.

More from Serban
Keep reading

Related posts

All posts
Component guides

React Phone Input With Country Code and E.164 Value

A React phone input that formats per country as you type, picks the country from a pasted +code, validates with libphonenumber-js and returns one E.164 value.

SRSerban Rusu·Oct 13, 2026·8 min read
Component guides

React Form Components: Accessible Fields, Zod and Mobile

React form components that share one anatomy (label, hint, error, counter), plug into react-hook-form and zod, and behave right on a phone, with full code.

SRSerban Rusu·Oct 9, 2026·26 min read
Component guides

Shadcn Number Input: Steppers, Min, Max and Decimals

Why type=number fails as a shadcn number input (scroll, arrows, commas) and how to build one with steppers, hold to repeat, min, max, step and Intl formatting.

SRSerban Rusu·Nov 6, 2026·8 min read
Newsletter

Get new posts by email

New posts, product news and occasional offers from Wingo UI. We count clicks to keep it relevant.

No spam. Unsubscribe at any time.

WingoUI

Animated, configurable, mobile-first React components and blocks. Copy the source, make it yours, and let your coding agent build with it.

Product

  • Components
  • Templates
  • Pricing
  • AI agents
  • For teams
  • Theme generator

Resources

  • Docs
  • Contact
  • Programs
  • Blog
  • Changelog
  • Changelog RSS
  • llms.txt

Compare

  • Wingo UI vs paid kits
  • Wingo UI vs shadcn/ui
  • shadcn/ui alternatives
  • MUI alternatives
  • Tailwind Plus alternatives
  • Magic UI alternatives
  • Free components

Legal

  • Terms
  • Privacy
  • Refunds
  • License
  • Imprint

Component categories

  • Buttons & Actions
  • Inputs
  • Forms
  • Navigation
  • Overlays
  • Feedback
  • Data Display
  • Tables & Lists
  • Charts & Stats
  • Layout
  • Media
  • AI Kit
  • Text & Effects
  • Mobile
  • Commerce
  • Marketing Sections
  • Blocks
  • Hooks & Utilities

© 2026 Wingo UI

Wingo UI