1001Ferramentas
๐ŸšฉValidators

Flag Emoji Validator

Check if an emoji is a valid country flag (Regional Indicator Symbols). Shows ISO 3166-1 alpha-2.

Flag emoji validation: how Unicode encodes a country in two characters

A flag emoji like ๐Ÿ‡ง๐Ÿ‡ท is not a single character in Unicode โ€” it is a pair of Regional Indicator Symbol Letters (RIS) that together form the ISO 3166-1 alpha-2 country code. The flag of Brazil is the letters B + R rendered as a sequence: ๐Ÿ‡ง (U+1F1E7) followed by ๐Ÿ‡ท (U+1F1F7). The flag of the United States is ๐Ÿ‡บ + ๐Ÿ‡ธ (U+1F1FA + U+1F1F8). The font and operating system are the only thing that turns the pair into an actual flag glyph โ€” at the byte level it is just two indicator letters.

This means flag validation has two layers: (1) is the input syntactically two Regional Indicator codepoints, and (2) does the resulting alpha-2 pair correspond to a recognised ISO 3166-1 country? A string can pass the first check and still fail the second โ€” combinations like ๐Ÿ‡ฝ๐Ÿ‡ฝ (XX) are well-formed sequences but render as the two raw letters because no country has that code.

The Regional Indicator block: U+1F1E6 to U+1F1FF

Unicode reserves 26 codepoints in the Supplementary Multilingual Plane for the Regional Indicators:

  • U+1F1E6 = ๐Ÿ‡ฆ, U+1F1E7 = ๐Ÿ‡ง, U+1F1E8 = ๐Ÿ‡จ, ... U+1F1FF = ๐Ÿ‡ฟ
  • Each indicator is 4 bytes in UTF-8 โ€” a flag emoji is therefore 8 bytes, twice the length of a basic emoji.
  • String.length in JavaScript returns 4 for a single flag (two surrogate pairs), not 1.
  • To count flags correctly use the iterator protocol: [...'๐Ÿ‡ง๐Ÿ‡ท'].length === 2, then group pairs.

The validation regex with the Unicode flag is direct:

const flagRegex = /^[\u{1F1E6}-\u{1F1FF}]{2}$/u

function isFlagEmoji(str) {
  if (!flagRegex.test(str)) return false
  const chars = [...str]
  const a = chars[0].codePointAt(0) - 0x1F1E6
  const b = chars[1].codePointAt(0) - 0x1F1E6
  const code = String.fromCharCode(65 + a, 65 + b)  // alpha-2
  return ISO_3166_1.has(code)
}

Subdivisions, special flags and Tag Sequences

A handful of flags fall outside the Regional Indicator pattern:

  • England ๐Ÿด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟ, Scotland ๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ, Wales ๐Ÿด๓ ง๓ ข๓ ท๓ ฌ๓ ณ๓ ฟ โ€” use a Tag Sequence: a black flag base (U+1F3F4) plus invisible Tag characters spelling out the ISO 3166-2 subdivision code (gb-eng, gb-sct, gb-wls), terminated by U+E007F.
  • Pirate flag ๐Ÿดโ€โ˜ ๏ธ โ€” black flag + ZWJ (Zero-Width Joiner) + skull and crossbones.
  • Rainbow flag ๐Ÿณ๏ธโ€๐ŸŒˆ โ€” white flag + variation selector + ZWJ + rainbow.
  • Transgender flag ๐Ÿณ๏ธโ€โšง๏ธ โ€” same ZWJ pattern with the gender symbol.

The total of country/territory flags is roughly 250, matching the active ISO 3166-1 list. The Unicode CLDR (Common Locale Data Repository) provides localised country names for each โ€” useful when you want to show "Brasil" next to ๐Ÿ‡ง๐Ÿ‡ท in a Portuguese UI and "Brazil" in an English UI.

Platform inconsistencies and political sensitivities

Rendering is platform-dependent and politically loaded. Apple's emoji font ships real flag glyphs for every country; Google's Noto Color Emoji does the same. Microsoft Windows historically rendered the bare Regional Indicator letters instead of a glyph โ€” that finally changed with Windows 11. The Taiwan flag ๐Ÿ‡น๐Ÿ‡ผ is the canonical example: on iOS the device hides it when the system region is set to mainland China; some Chinese-market Android builds skip it entirely. ๐Ÿ‡ฝ๐Ÿ‡ฐ Kosovo was added late and is still inconsistent. ๐Ÿ‡ช๐Ÿ‡บ European Union uses the special code EU that is technically reserved, not assigned.

For applications, this means: never assume the same flag emoji will render identically on every device. Show the country name as a fallback, especially in accessibility contexts where screen readers may announce only the alpha-2 code.

Use cases in Brazilian apps

Flag emojis appear in language switchers (๐Ÿ‡ง๐Ÿ‡ท / ๐Ÿ‡บ๐Ÿ‡ธ / ๐Ÿ‡ช๐Ÿ‡ธ), country pickers in e-commerce checkout, WhatsApp Status, Instagram bios, push-notification badges and CDN region indicators. The biggest pitfall is using a flag to indicate a language instead of a country โ€” Spanish is spoken in 21 countries, and choosing ๐Ÿ‡ช๐Ÿ‡ธ over ๐Ÿ‡ฒ๐Ÿ‡ฝ is a political signal users notice. The safe pattern is to label the option by language code (pt-BR, en-US) and put the flag next to it as decoration, never as the sole identifier.

FAQ

How many country flags exist? About 250, matching ISO 3166-1. Subdivisions add a few more via Tag Sequences (England, Scotland, Wales, Texas in some fonts), and special flags (pirate, rainbow, transgender) use ZWJ sequences.

Why does my code see length 4 for ๐Ÿ‡ง๐Ÿ‡ท? JavaScript strings are UTF-16. Each Regional Indicator is in the supplementary plane and occupies two surrogate code units, so a flag is 4 UTF-16 code units. Use [...str] or str.codePointAt to count actual characters.

Why does the Taiwan flag disappear on some devices? Apple and some Chinese-market Android builds hide ๐Ÿ‡น๐Ÿ‡ผ when the device region is set to mainland China, for regulatory reasons. The underlying codepoint sequence is still there in the data โ€” only the rendered glyph changes.

Are subdivision flags Tag Sequences? Yes. England, Scotland and Wales use the black-flag base plus ISO 3166-2 codes in Tag characters. Most fonts render them as the regional flag; older fonts fall back to the bare black flag.

Can I validate without an ISO 3166 table? Only structurally โ€” you can confirm the input is two Regional Indicators, but you cannot tell whether the pair encodes a real country without the lookup list. Combinations like ๐Ÿ‡ฝ๐Ÿ‡ฝ pass the regex but are not flags.

Related Tools