--- title: "MazSelectCountry" description: "MazSelectCountry is a versatile Vue component for selecting countries or languages with built-in internationalization support and customizable display options" package: "maz-ui" url: "https://maz-ui.com/components/maz-select-country" --- # MazSelectCountry > MazSelectCountry is a versatile Vue component for selecting countries or languages with built-in internationalization support and customizable display options - Package: `maz-ui` - Import: `import MazSelectCountry from 'maz-ui/components/MazSelectCountry'` - Nuxt: auto-imported by `@maz-ui/nuxt`, no import needed in a Nuxt app - Web: https://maz-ui.com/components/maz-select-country **Tip:** This component can be translated globally using the [MazUi](../ecosystem/translations.md) plugin. ## Basic usage The most common use case is selecting a country. The component automatically displays country names in the user's locale with their respective flags. ```vue ``` ## Language selection Configure the component to display languages instead of countries by setting the appropriate `displayNamesOptions`. ```vue ``` ## Sizes and colors ```vue ``` ## Preferred countries You can prioritize certain countries to appear at the top of the list using the `preferredCodes` prop. ```vue ``` ## Filtering options Control which countries are displayed using `onlyCodes` to show only specific countries, or `ignoredCodes` to exclude certain ones. ```vue ``` ## Custom display options Configure how country/language names are displayed using the `displayNamesOptions` prop, which leverages the browser's `Intl.DisplayNames` API. ```vue ``` ## Flags source By default, the flags are images of the [flagcdn.com](https://flagcdn.com) CDN: each user's browser requests them from this third party. The `flag-src` prop changes where they come from, in four ways: | Source | `flag-src` | Network | | --- | --- | --- | | CDN (default) | not set | flagcdn.com | | Flags of maz-ui | `loadCountryFlag` from `maz-ui/country-flags` | none (works offline) | | Your own files | URL template: `'/flags/{code}.svg'` | your server | | Your own function | `(code) => string \| undefined \| Promise` | yours | In every case, a flag is only loaded when it becomes visible (the selected country, then the rows of the open list in view), and a code without flag displays the colored badge. ### For the whole app Set it once instead of on every component: the `flag-src` of `MazSelectCountry` and `MazInputPhoneNumber` both default to `defaults.global.flagSrc` (see [Global component defaults](../guide/global-defaults.md)). A `flag-src` set on a component always wins. ```ts // Vue: main.ts import { loadCountryFlag } from 'maz-ui/country-flags' import { MazUi } from 'maz-ui/plugins/maz-ui' app.use(MazUi, { theme: { preset: mazUi }, defaults: { global: { flagSrc: loadCountryFlag }, // or a URL template: '/flags/{code}.svg' }, }) ``` ```ts // Nuxt: nuxt.config.ts export default defineNuxtConfig({ modules: ['@maz-ui/nuxt'], mazUi: { flags: 'local', // 'cdn' (default) | 'local' | a URL template: '/flags/{code}.svg' }, }) ``` ### Flags of maz-ui, offline `loadCountryFlag` gives the square flag of a code from the 256 flags of `@maz-ui/icons`, as a `data:image/svg+xml` URL: no request to a third party (nothing to allow for flagcdn.com in your Content Security Policy, the user's IP is not sent to it), and the component works offline (hybrid apps with Capacitor or Cordova, PWAs, intranets). ```vue ``` How it stays light: - Nothing in maz-ui imports `maz-ui/country-flags`: an app that does not import it has **no flag file at all** in its build. - Once imported, your bundler emits **one small chunk per flag** (256 files, from a few hundred bytes to a few kilobytes each). None is preloaded: only the flags displayed are downloaded. - The loader itself (a table of 256 dynamic imports, about 4 kB gzipped) goes into the chunk that imports it. To keep it out of your entry chunk, import it on demand (the Nuxt option `flags: 'local'` does it for you): ```ts const flagSrc = (code: string) => import('maz-ui/country-flags').then(({ loadCountryFlag }) => loadCountryFlag(code)) ``` **Tip: Content Security Policy** The flags are `data:` URLs: a strict CSP must allow `img-src data:` (already needed by the lazy images of maz-ui). **Tip: PWA precache** Once you use `loadCountryFlag`, the 256 flag chunks are part of your build, so a service worker that precaches every `**/*.js` downloads all of them at install. Keep them (every flag available offline) or exclude them and let them load on demand. With Vite, the chunks are named after their module, `MazFlagSquareFR-[hash].js`: ```ts // vite-plugin-pwa VitePWA({ workbox: { globIgnores: ['**/MazFlagSquare*.js'] } }) ``` Nuxt names its chunks `_nuxt/[hash].js` only: name the flag chunks yourself to exclude them, e.g. `vite.build.rollupOptions.output.chunkFileNames: chunk => chunk.name.startsWith('MazFlagSquare') ? '_nuxt/flags/[name].[hash].js' : '_nuxt/[hash].js'`, then ignore `**/_nuxt/flags/**`. ### Your own files A URL template, with `{code}` for the lowercase code and `{CODE}` for the uppercase code. The images are lazy loaded like the CDN ones. A missing image displays the badge. ```vue ``` ### Your own function A function receives the country code of each flag when it becomes visible, and returns the image source (URL or data URL), or `undefined` to display the badge. It can be async: only the flags displayed are loaded. ```vue ``` You can also replace the flags entirely with the `selector-flag` and `country-list-flag` slots. ## Without flags Hide country flags using the `hideFlags` prop for a cleaner text-only interface. ```vue ``` ## Custom locale Override the default locale to display country/language names in a specific language. ```vue ``` ## States and validation The component supports all the standard form states for better user experience. ```vue ``` ## Custom options Provide your own list of options instead of using the built-in country/language codes. ```vue ``` ## Display code instead of name Show country/language codes in the input field instead of names using the `displayCode` prop. ```vue ``` ## Advanced configuration Combine multiple features for complex use cases, such as business applications requiring specific country lists with custom styling. ```vue ``` ## How it works The `MazSelectCountry` component is built on top of `MazSelect` and leverages the powerful `useDisplayNames` composable, which uses the browser's native `Intl.DisplayNames` API for internationalization. ### Key features: - **Automatic localization**: Country and language names are displayed in the user's locale - **Built-in search**: Users can quickly find countries by typing - **Flag integration**: Automatic flag display using country codes, from the flagcdn.com CDN, the flags of maz-ui (offline) or your own files - **Flexible filtering**: Support for preferred, ignored, or specific country lists - **Custom options**: Override default behavior with custom data - **Accessibility**: Full keyboard navigation and screen reader support ### useDisplayNames composable The component uses the `useDisplayNames` composable internally, which provides: ```typescript // Get display name for a single code const displayName = getDisplayName('FR', { locale: 'en-US', type: 'region' }) // Get all display names with filtering const allCountries = getAllDisplayNames({ locale: 'en-US', codesType: 'country', preferred: ['US', 'GB', 'FR'], exclude: ['AQ'] }) ``` This ensures consistent internationalization across your application while providing maximum flexibility for different use cases. ## MazSelectCountry API `import MazSelectCountry from 'maz-ui/components/MazSelectCountry'` ### Props - `id` (`string`): Id of the component. - `color` (`"primary" | "secondary" | "accent" | "info" | "success" | "warning" | "destructive" | "contrast" | "transparent"`, default: `"primary"`): Color of the component. - `size` (`"xs" | "sm" | "md" | "lg" | "xl" | "mini"`, default: `md`): Size of the component. - `preferred-codes` (`Option["code"][]`): Preferred countries to display. - `ignored-codes` (`Option["code"][]`): Ignored countries to display. - `only-codes` (`Option["code"][]`): Only countries to display. - `list-position` (`MazPopoverPosition`, default: `'auto'`): Position of the list. - `hide-flags` (`boolean`): Hide flags. - `flag-src` (`MazCountryFlagSrc`, default: `undefined (flags from flagcdn.com)`): Source of the flags, instead of the flagcdn.com CDN: - a URL template with the code, `{code}` (lowercase) or `{CODE}` (uppercase): `/flags/{code}.svg` - a function giving the image source of a code (URL or data URL), called when the flag becomes visible, or `undefined` to display the code in a badge Use `loadCountryFlag` from `maz-ui/country-flags` for the flags of `@maz-ui/icons`, without any request to a third party. Can be set for the whole app with the `defaults.global.flagSrc` option of the MazUi plugin. - `search` (`boolean`, default: `true`): Display search input in options list. - `show-code-in-list` (`boolean`, default: `false`): Show code on list. - `locale` (`string`, default: `locale defined within the maz-ui plugin or browser locale or en-US`): Locale. - `success` (`boolean`): Success state. - `error` (`boolean`): Error state. - `warning` (`boolean`): Warning state. - `display-code` (`boolean`) - `search-threshold` (`number`, default: `0.75`): Search threshold. - `translations` (`Partial<{ searchPlaceholder: string; }>`, default: `MazUiTranslationsNestedSchema['selectCountry']`): Translations. - `hint` (`string`): Hint message displayed. - `options` (`Option[]`): Options. - `display-names-options` (`DisplayNamesOptions`, default: `{ type: "region", languageDisplay: "standard", fallback: "code", style: "long", }`): Display name type. - `codes-type` (`CodesType`, default: `defined by displayNamesOptions.type (if 'region', 'country' is used, otherwise 'iso')`): Codes type. Values: `'iso'`, `'bcp'`, `'country'`, `'all'` (non exhaustive). - `open` (`boolean`, default: `false`): Open the select. - `model-value` (`Option["code"]`, `v-model`): The value of the select. - `block` (`boolean`): The input will be displayed in full width. - `disabled` (`boolean`): Disable the component. - `required` (`boolean`): Make the input required in the form. - `placeholder` (`string`): The placeholder of the select. - `label` (`string`): The label of the select. - `search-function` (`((query: string, options: Option[]) => Option[] | undefined)`): Replace the default search function to provide a custom search function. - `transition` (`string`, default: `'scale-fade'`): The transition name of the panel list options. - `prefer-position` (`MazPopoverPreferPosition`, default: `'bottom-start'`): The prefer position of the list. - `fallback-position` (`MazPopoverFallbackPosition`, default: `'top-start'`): The fallback position of the list. - `top-label` (`string`): Static label displayed above the input field. Unlike the floating label, this remains fixed. - `autocomplete` (`string`, default: `'off'`): The autocomplete attribute of the input. - `option-value-key` (`string`, default: `"code"`): The key of the option value. - `option-label-key` (`string`, default: `"name"`): The key of the option label. - `option-input-value-key` (`string`, default: `"name"`): The key of the option input value. - `item-height` (`number`): The height of the option list item. - `max-list-height` (`number`, default: `240`): The max height of the option list. - `max-list-width` (`number`, default: `250`): The max width of the option list. - `min-list-height` (`number`): The min height of the option list. - `min-list-width` (`number`, default: `200`): The min width of the option list. - `format-input-value` (`((value: Option["code"]) => string)`): The function to format the input value. ### Events - `@update:model-value` (payload: `value?: Option["code"] | undefined`): Emitted when the model value changes ### Slots - `#selector-flag`: Country selector flag Bindings: `countryCode: Option["code"]` (current selected country code - Ex: `"FR"`). - `#no-results` - `#country-list-flag`: Country list flag Bindings: `option: Option` (country data), `isSelected: boolean` (`true` if option is selected). - `#country-list-code` Bindings: `option: Option`, `isSelected: boolean`. - `#country-list-name` Bindings: `option: Option`, `isSelected: boolean`.