countries.ts319 lines · main
| 1 | /** |
| 2 | * ISO 3166-1 alpha-2 country list used in the Settings → Profile country |
| 3 | * dropdown. Mirrors the set Polar accepts on its billing-address field |
| 4 | * (Polar, via Stripe under the hood, supports the full alpha-2 space — |
| 5 | * see https://polar.sh/docs/api-reference/). |
| 6 | * |
| 7 | * EU/EEA members are pinned first so they surface as the common case for |
| 8 | * invoices + VAT. Everything else follows alphabetically by English name. |
| 9 | */ |
| 10 | |
| 11 | export interface Country { |
| 12 | readonly code: string; |
| 13 | readonly name: string; |
| 14 | } |
| 15 | |
| 16 | const EU_CODES = new Set([ |
| 17 | 'AT', |
| 18 | 'BE', |
| 19 | 'BG', |
| 20 | 'CY', |
| 21 | 'CZ', |
| 22 | 'DE', |
| 23 | 'DK', |
| 24 | 'EE', |
| 25 | 'ES', |
| 26 | 'FI', |
| 27 | 'FR', |
| 28 | 'GR', |
| 29 | 'HR', |
| 30 | 'HU', |
| 31 | 'IE', |
| 32 | 'IT', |
| 33 | 'LT', |
| 34 | 'LU', |
| 35 | 'LV', |
| 36 | 'MT', |
| 37 | 'NL', |
| 38 | 'PL', |
| 39 | 'PT', |
| 40 | 'RO', |
| 41 | 'SE', |
| 42 | 'SI', |
| 43 | 'SK', |
| 44 | // EEA non-EU |
| 45 | 'IS', |
| 46 | 'LI', |
| 47 | 'NO', |
| 48 | // neighbouring |
| 49 | 'CH', |
| 50 | 'GB', |
| 51 | ]); |
| 52 | |
| 53 | const ALL: ReadonlyArray<Country> = [ |
| 54 | { code: 'AF', name: 'Afghanistan' }, |
| 55 | { code: 'AL', name: 'Albania' }, |
| 56 | { code: 'DZ', name: 'Algeria' }, |
| 57 | { code: 'AS', name: 'American Samoa' }, |
| 58 | { code: 'AD', name: 'Andorra' }, |
| 59 | { code: 'AO', name: 'Angola' }, |
| 60 | { code: 'AI', name: 'Anguilla' }, |
| 61 | { code: 'AQ', name: 'Antarctica' }, |
| 62 | { code: 'AG', name: 'Antigua and Barbuda' }, |
| 63 | { code: 'AR', name: 'Argentina' }, |
| 64 | { code: 'AM', name: 'Armenia' }, |
| 65 | { code: 'AW', name: 'Aruba' }, |
| 66 | { code: 'AU', name: 'Australia' }, |
| 67 | { code: 'AT', name: 'Austria' }, |
| 68 | { code: 'AZ', name: 'Azerbaijan' }, |
| 69 | { code: 'BS', name: 'Bahamas' }, |
| 70 | { code: 'BH', name: 'Bahrain' }, |
| 71 | { code: 'BD', name: 'Bangladesh' }, |
| 72 | { code: 'BB', name: 'Barbados' }, |
| 73 | { code: 'BY', name: 'Belarus' }, |
| 74 | { code: 'BE', name: 'Belgium' }, |
| 75 | { code: 'BZ', name: 'Belize' }, |
| 76 | { code: 'BJ', name: 'Benin' }, |
| 77 | { code: 'BM', name: 'Bermuda' }, |
| 78 | { code: 'BT', name: 'Bhutan' }, |
| 79 | { code: 'BO', name: 'Bolivia' }, |
| 80 | { code: 'BQ', name: 'Bonaire, Sint Eustatius and Saba' }, |
| 81 | { code: 'BA', name: 'Bosnia and Herzegovina' }, |
| 82 | { code: 'BW', name: 'Botswana' }, |
| 83 | { code: 'BV', name: 'Bouvet Island' }, |
| 84 | { code: 'BR', name: 'Brazil' }, |
| 85 | { code: 'IO', name: 'British Indian Ocean Territory' }, |
| 86 | { code: 'BN', name: 'Brunei Darussalam' }, |
| 87 | { code: 'BG', name: 'Bulgaria' }, |
| 88 | { code: 'BF', name: 'Burkina Faso' }, |
| 89 | { code: 'BI', name: 'Burundi' }, |
| 90 | { code: 'CV', name: 'Cabo Verde' }, |
| 91 | { code: 'KH', name: 'Cambodia' }, |
| 92 | { code: 'CM', name: 'Cameroon' }, |
| 93 | { code: 'CA', name: 'Canada' }, |
| 94 | { code: 'KY', name: 'Cayman Islands' }, |
| 95 | { code: 'CF', name: 'Central African Republic' }, |
| 96 | { code: 'TD', name: 'Chad' }, |
| 97 | { code: 'CL', name: 'Chile' }, |
| 98 | { code: 'CN', name: 'China' }, |
| 99 | { code: 'CX', name: 'Christmas Island' }, |
| 100 | { code: 'CC', name: 'Cocos (Keeling) Islands' }, |
| 101 | { code: 'CO', name: 'Colombia' }, |
| 102 | { code: 'KM', name: 'Comoros' }, |
| 103 | { code: 'CG', name: 'Congo' }, |
| 104 | { code: 'CD', name: 'Congo, Democratic Republic of the' }, |
| 105 | { code: 'CK', name: 'Cook Islands' }, |
| 106 | { code: 'CR', name: 'Costa Rica' }, |
| 107 | { code: 'CI', name: "Côte d'Ivoire" }, |
| 108 | { code: 'HR', name: 'Croatia' }, |
| 109 | { code: 'CU', name: 'Cuba' }, |
| 110 | { code: 'CW', name: 'Curaçao' }, |
| 111 | { code: 'CY', name: 'Cyprus' }, |
| 112 | { code: 'CZ', name: 'Czechia' }, |
| 113 | { code: 'DK', name: 'Denmark' }, |
| 114 | { code: 'DJ', name: 'Djibouti' }, |
| 115 | { code: 'DM', name: 'Dominica' }, |
| 116 | { code: 'DO', name: 'Dominican Republic' }, |
| 117 | { code: 'EC', name: 'Ecuador' }, |
| 118 | { code: 'EG', name: 'Egypt' }, |
| 119 | { code: 'SV', name: 'El Salvador' }, |
| 120 | { code: 'GQ', name: 'Equatorial Guinea' }, |
| 121 | { code: 'ER', name: 'Eritrea' }, |
| 122 | { code: 'EE', name: 'Estonia' }, |
| 123 | { code: 'SZ', name: 'Eswatini' }, |
| 124 | { code: 'ET', name: 'Ethiopia' }, |
| 125 | { code: 'FK', name: 'Falkland Islands (Malvinas)' }, |
| 126 | { code: 'FO', name: 'Faroe Islands' }, |
| 127 | { code: 'FJ', name: 'Fiji' }, |
| 128 | { code: 'FI', name: 'Finland' }, |
| 129 | { code: 'FR', name: 'France' }, |
| 130 | { code: 'GF', name: 'French Guiana' }, |
| 131 | { code: 'PF', name: 'French Polynesia' }, |
| 132 | { code: 'TF', name: 'French Southern Territories' }, |
| 133 | { code: 'GA', name: 'Gabon' }, |
| 134 | { code: 'GM', name: 'Gambia' }, |
| 135 | { code: 'GE', name: 'Georgia' }, |
| 136 | { code: 'DE', name: 'Germany' }, |
| 137 | { code: 'GH', name: 'Ghana' }, |
| 138 | { code: 'GI', name: 'Gibraltar' }, |
| 139 | { code: 'GR', name: 'Greece' }, |
| 140 | { code: 'GL', name: 'Greenland' }, |
| 141 | { code: 'GD', name: 'Grenada' }, |
| 142 | { code: 'GP', name: 'Guadeloupe' }, |
| 143 | { code: 'GU', name: 'Guam' }, |
| 144 | { code: 'GT', name: 'Guatemala' }, |
| 145 | { code: 'GG', name: 'Guernsey' }, |
| 146 | { code: 'GN', name: 'Guinea' }, |
| 147 | { code: 'GW', name: 'Guinea-Bissau' }, |
| 148 | { code: 'GY', name: 'Guyana' }, |
| 149 | { code: 'HT', name: 'Haiti' }, |
| 150 | { code: 'HM', name: 'Heard Island and McDonald Islands' }, |
| 151 | { code: 'VA', name: 'Holy See' }, |
| 152 | { code: 'HN', name: 'Honduras' }, |
| 153 | { code: 'HK', name: 'Hong Kong' }, |
| 154 | { code: 'HU', name: 'Hungary' }, |
| 155 | { code: 'IS', name: 'Iceland' }, |
| 156 | { code: 'IN', name: 'India' }, |
| 157 | { code: 'ID', name: 'Indonesia' }, |
| 158 | { code: 'IR', name: 'Iran' }, |
| 159 | { code: 'IQ', name: 'Iraq' }, |
| 160 | { code: 'IE', name: 'Ireland' }, |
| 161 | { code: 'IM', name: 'Isle of Man' }, |
| 162 | { code: 'IL', name: 'Israel' }, |
| 163 | { code: 'IT', name: 'Italy' }, |
| 164 | { code: 'JM', name: 'Jamaica' }, |
| 165 | { code: 'JP', name: 'Japan' }, |
| 166 | { code: 'JE', name: 'Jersey' }, |
| 167 | { code: 'JO', name: 'Jordan' }, |
| 168 | { code: 'KZ', name: 'Kazakhstan' }, |
| 169 | { code: 'KE', name: 'Kenya' }, |
| 170 | { code: 'KI', name: 'Kiribati' }, |
| 171 | { code: 'KP', name: "Korea, Democratic People's Republic of" }, |
| 172 | { code: 'KR', name: 'Korea, Republic of' }, |
| 173 | { code: 'KW', name: 'Kuwait' }, |
| 174 | { code: 'KG', name: 'Kyrgyzstan' }, |
| 175 | { code: 'LA', name: "Lao People's Democratic Republic" }, |
| 176 | { code: 'LV', name: 'Latvia' }, |
| 177 | { code: 'LB', name: 'Lebanon' }, |
| 178 | { code: 'LS', name: 'Lesotho' }, |
| 179 | { code: 'LR', name: 'Liberia' }, |
| 180 | { code: 'LY', name: 'Libya' }, |
| 181 | { code: 'LI', name: 'Liechtenstein' }, |
| 182 | { code: 'LT', name: 'Lithuania' }, |
| 183 | { code: 'LU', name: 'Luxembourg' }, |
| 184 | { code: 'MO', name: 'Macao' }, |
| 185 | { code: 'MG', name: 'Madagascar' }, |
| 186 | { code: 'MW', name: 'Malawi' }, |
| 187 | { code: 'MY', name: 'Malaysia' }, |
| 188 | { code: 'MV', name: 'Maldives' }, |
| 189 | { code: 'ML', name: 'Mali' }, |
| 190 | { code: 'MT', name: 'Malta' }, |
| 191 | { code: 'MH', name: 'Marshall Islands' }, |
| 192 | { code: 'MQ', name: 'Martinique' }, |
| 193 | { code: 'MR', name: 'Mauritania' }, |
| 194 | { code: 'MU', name: 'Mauritius' }, |
| 195 | { code: 'YT', name: 'Mayotte' }, |
| 196 | { code: 'MX', name: 'Mexico' }, |
| 197 | { code: 'FM', name: 'Micronesia' }, |
| 198 | { code: 'MD', name: 'Moldova' }, |
| 199 | { code: 'MC', name: 'Monaco' }, |
| 200 | { code: 'MN', name: 'Mongolia' }, |
| 201 | { code: 'ME', name: 'Montenegro' }, |
| 202 | { code: 'MS', name: 'Montserrat' }, |
| 203 | { code: 'MA', name: 'Morocco' }, |
| 204 | { code: 'MZ', name: 'Mozambique' }, |
| 205 | { code: 'MM', name: 'Myanmar' }, |
| 206 | { code: 'NA', name: 'Namibia' }, |
| 207 | { code: 'NR', name: 'Nauru' }, |
| 208 | { code: 'NP', name: 'Nepal' }, |
| 209 | { code: 'NL', name: 'Netherlands' }, |
| 210 | { code: 'NC', name: 'New Caledonia' }, |
| 211 | { code: 'NZ', name: 'New Zealand' }, |
| 212 | { code: 'NI', name: 'Nicaragua' }, |
| 213 | { code: 'NE', name: 'Niger' }, |
| 214 | { code: 'NG', name: 'Nigeria' }, |
| 215 | { code: 'NU', name: 'Niue' }, |
| 216 | { code: 'NF', name: 'Norfolk Island' }, |
| 217 | { code: 'MK', name: 'North Macedonia' }, |
| 218 | { code: 'MP', name: 'Northern Mariana Islands' }, |
| 219 | { code: 'NO', name: 'Norway' }, |
| 220 | { code: 'OM', name: 'Oman' }, |
| 221 | { code: 'PK', name: 'Pakistan' }, |
| 222 | { code: 'PW', name: 'Palau' }, |
| 223 | { code: 'PS', name: 'Palestine' }, |
| 224 | { code: 'PA', name: 'Panama' }, |
| 225 | { code: 'PG', name: 'Papua New Guinea' }, |
| 226 | { code: 'PY', name: 'Paraguay' }, |
| 227 | { code: 'PE', name: 'Peru' }, |
| 228 | { code: 'PH', name: 'Philippines' }, |
| 229 | { code: 'PN', name: 'Pitcairn' }, |
| 230 | { code: 'PL', name: 'Poland' }, |
| 231 | { code: 'PT', name: 'Portugal' }, |
| 232 | { code: 'PR', name: 'Puerto Rico' }, |
| 233 | { code: 'QA', name: 'Qatar' }, |
| 234 | { code: 'RE', name: 'Réunion' }, |
| 235 | { code: 'RO', name: 'Romania' }, |
| 236 | { code: 'RU', name: 'Russian Federation' }, |
| 237 | { code: 'RW', name: 'Rwanda' }, |
| 238 | { code: 'BL', name: 'Saint Barthélemy' }, |
| 239 | { code: 'SH', name: 'Saint Helena' }, |
| 240 | { code: 'KN', name: 'Saint Kitts and Nevis' }, |
| 241 | { code: 'LC', name: 'Saint Lucia' }, |
| 242 | { code: 'MF', name: 'Saint Martin (French part)' }, |
| 243 | { code: 'PM', name: 'Saint Pierre and Miquelon' }, |
| 244 | { code: 'VC', name: 'Saint Vincent and the Grenadines' }, |
| 245 | { code: 'WS', name: 'Samoa' }, |
| 246 | { code: 'SM', name: 'San Marino' }, |
| 247 | { code: 'ST', name: 'Sao Tome and Principe' }, |
| 248 | { code: 'SA', name: 'Saudi Arabia' }, |
| 249 | { code: 'SN', name: 'Senegal' }, |
| 250 | { code: 'RS', name: 'Serbia' }, |
| 251 | { code: 'SC', name: 'Seychelles' }, |
| 252 | { code: 'SL', name: 'Sierra Leone' }, |
| 253 | { code: 'SG', name: 'Singapore' }, |
| 254 | { code: 'SX', name: 'Sint Maarten (Dutch part)' }, |
| 255 | { code: 'SK', name: 'Slovakia' }, |
| 256 | { code: 'SI', name: 'Slovenia' }, |
| 257 | { code: 'SB', name: 'Solomon Islands' }, |
| 258 | { code: 'SO', name: 'Somalia' }, |
| 259 | { code: 'ZA', name: 'South Africa' }, |
| 260 | { code: 'GS', name: 'South Georgia and the South Sandwich Islands' }, |
| 261 | { code: 'SS', name: 'South Sudan' }, |
| 262 | { code: 'ES', name: 'Spain' }, |
| 263 | { code: 'LK', name: 'Sri Lanka' }, |
| 264 | { code: 'SD', name: 'Sudan' }, |
| 265 | { code: 'SR', name: 'Suriname' }, |
| 266 | { code: 'SJ', name: 'Svalbard and Jan Mayen' }, |
| 267 | { code: 'SE', name: 'Sweden' }, |
| 268 | { code: 'CH', name: 'Switzerland' }, |
| 269 | { code: 'SY', name: 'Syrian Arab Republic' }, |
| 270 | { code: 'TW', name: 'Taiwan' }, |
| 271 | { code: 'TJ', name: 'Tajikistan' }, |
| 272 | { code: 'TZ', name: 'Tanzania' }, |
| 273 | { code: 'TH', name: 'Thailand' }, |
| 274 | { code: 'TL', name: 'Timor-Leste' }, |
| 275 | { code: 'TG', name: 'Togo' }, |
| 276 | { code: 'TK', name: 'Tokelau' }, |
| 277 | { code: 'TO', name: 'Tonga' }, |
| 278 | { code: 'TT', name: 'Trinidad and Tobago' }, |
| 279 | { code: 'TN', name: 'Tunisia' }, |
| 280 | { code: 'TR', name: 'Türkiye' }, |
| 281 | { code: 'TM', name: 'Turkmenistan' }, |
| 282 | { code: 'TC', name: 'Turks and Caicos Islands' }, |
| 283 | { code: 'TV', name: 'Tuvalu' }, |
| 284 | { code: 'UG', name: 'Uganda' }, |
| 285 | { code: 'UA', name: 'Ukraine' }, |
| 286 | { code: 'AE', name: 'United Arab Emirates' }, |
| 287 | { code: 'GB', name: 'United Kingdom' }, |
| 288 | { code: 'US', name: 'United States' }, |
| 289 | { code: 'UM', name: 'United States Minor Outlying Islands' }, |
| 290 | { code: 'UY', name: 'Uruguay' }, |
| 291 | { code: 'UZ', name: 'Uzbekistan' }, |
| 292 | { code: 'VU', name: 'Vanuatu' }, |
| 293 | { code: 'VE', name: 'Venezuela' }, |
| 294 | { code: 'VN', name: 'Viet Nam' }, |
| 295 | { code: 'VG', name: 'Virgin Islands (British)' }, |
| 296 | { code: 'VI', name: 'Virgin Islands (U.S.)' }, |
| 297 | { code: 'WF', name: 'Wallis and Futuna' }, |
| 298 | { code: 'EH', name: 'Western Sahara' }, |
| 299 | { code: 'YE', name: 'Yemen' }, |
| 300 | { code: 'ZM', name: 'Zambia' }, |
| 301 | { code: 'ZW', name: 'Zimbabwe' }, |
| 302 | ]; |
| 303 | |
| 304 | const byName = (a: Country, b: Country) => a.name.localeCompare(b.name); |
| 305 | |
| 306 | /** |
| 307 | * EU/EEA + UK/CH pinned first (common case for invoicing + reverse-charge |
| 308 | * VAT), then every other country alphabetically. A single `<optgroup>` in |
| 309 | * the form separates the two blocks visually. |
| 310 | */ |
| 311 | export const COUNTRIES_EU: ReadonlyArray<Country> = ALL.filter((c) => EU_CODES.has(c.code)).sort( |
| 312 | byName, |
| 313 | ); |
| 314 | |
| 315 | export const COUNTRIES_REST: ReadonlyArray<Country> = ALL.filter((c) => !EU_CODES.has(c.code)).sort( |
| 316 | byName, |
| 317 | ); |
| 318 | |
| 319 | export const COUNTRIES: ReadonlyArray<Country> = [...COUNTRIES_EU, ...COUNTRIES_REST]; |