Plug-and-play widgets that inject country and subdivision data into your existing select elements
Widgets are JavaScript scripts that automatically populate your existing select elements with country and subdivision data. They work by detecting elements with specific CSS classes and injecting data via API calls, without modifying your styling or layout.
Configure individual widget behavior, styling, and data attributes for your select elements.
Widgets work by adding CSS classes to your existing select elements. The widget script automatically detects these elements and injects country and subdivision data without modifying your styling or layout.
This example uses the following configuration:
Add the JavaScript script with your valid public key: <script src="https://unpkg.com/@countriesdb/widget@latest/dist/index.js?public_key=YOUR_PUBLIC_KEY"></script>
Add class="country-selection" to your country select element.
Configure allowed domains in your dashboard for Start and Basic plans. Pro and Full plans have no domain restrictions.
Configure available languages in your dashboard for Start and Basic plans. Pro and Full plans have all languages included.
When using client-side routing (React Router, Next.js, Vue Router, etc.), your page can change without a full refresh. The widget scans the DOM for .country-selection / .subdivision-selection during initialization, so on route navigation you should call CountriesWidgetLoad({ reload: true }) to re-scan and re-bind. This call should happen after you set window.CountriesDBConfig (typically in your route/page component).
Subdivisions are an optional feature that allows users to select states, provinces, or other administrative divisions within countries. The availability of subdivisions depends on your selected plan. They come in two forms: official ISO names and extended names to multiple languages, providing comprehensive coverage for international applications.
This example uses the following configuration:
Subdivisions will only work if included in your plan. Check your dashboard for plan details and subdivision availability.
Add class="subdivision-selection" to your subdivision select element.
Use data-name="country_select_name" on country select and data-country="country_select_name" on subdivision select to link them together. You can name it however you like and have multiple country/subdivision pairs per form or page.
By default, the widget automatically preselects the country based on the user's location. You can disable this behavior using data-preselected="" to show custom labels or when geolocation is not needed.
The data-label attribute allows you to customize the default option text in your select elements. This is useful for providing clear instructions to users about what they should select.
The data-default-value attribute allows you to customize the value of the default option in your select elements. By default, the widget uses an empty string ("") as the value for the default option. You can set this to any value you need for your form processing or validation logic.
The data-country-code attribute allows subdivision selects to work independently by specifying the country directly. This is useful when you only need subdivision selection for a specific country, without requiring a separate country select element. The subdivision select will automatically load subdivisions for the specified country.
The data-nested1-prefix and data-nested2-prefix attributes allow you to customize the visual indentation for different levels of nested subdivisions. This is useful for countries with multi-level administrative hierarchies where you want to visually distinguish between different subdivision levels (e.g., states/provinces vs counties/districts).
Add `data-prefer-official` to individual subdivision selects when you only want specific fields to use official ISO subdivisions instead of extended translations. This is useful when you want most selects to use extended data but specific fields to use official ISO data.
Official preference only takes effect when your plan has extended subdivisions available. If your plan only includes official subdivisions (or none), the flag is ignored and the appropriate default is used automatically.
Use the standard HTML multiple attribute on your select elements. The widget will populate options as usual and dispatch countriesWidget:update with detail.selectedValues as an array of selected codes. This works for both country and subdivision selects.
Listen to the custom countriesWidget:update event to react to both user-initiated and widget-initiated changes (preselected, geoip, reload). The widget dispatches this event on the affected select element with useful detail like reason and type.
countriesWidget:ready fires separately for every select. The country select dispatches its own ready event as soon as its options are available, and each subdivision select dispatches another ready event every time it finishes loading data (initial load + every reload triggered by a country change). Use this to wait for data before touching the DOM, then inspect event.detail (type, value, phase) to know which select finished.
These settings are applied to the entire widget script and affect all select elements on the page. Define them inside `window.CountriesDBConfig` before the widget loads (or pass them via script URL params when using the CDN).
By default, the widget displays country and subdivision names using the user's browser language (Accept-Language). You can override this globally by adding `forced_language` to the script URL or setting `forcedLanguage` in `window.CountriesDBConfig`. Below we force Spanish (es) so all names are shown in Spanish regardless of the user's browser settings. If a translation is not available, the widget falls back to English.
The widget automatically uses the end user's browser language (Accept-Language). When a matching translation is not available, you can provide a fallback by adding `default_language` to the script URL or setting `defaultLanguage` in `window.CountriesDBConfig`. This value is used only when `forcedLanguage` is not set and when the browser language cannot be resolved to a supported translation. Subdivision names appear in the chosen language if available (official ISO and/or extended translations depending on your plan); otherwise they fall back to English.
The `follow_upward` parameter enables automatic navigation up the subdivision hierarchy, but only for cases where a subdivision is also a country itself (like Guam, Puerto Rico, etc.). Add `follow_upward=1` to the script URL or set `followUpward: true` in `window.CountriesDBConfig`. When enabled, selecting such a subdivision will automatically change the country to the parent country of that subdivision. For example, selecting Guam from the subdivision dropdown will automatically change the country selection to United States. This is useful for applications that need to handle complex country-territory relationships where territories are both subdivisions and countries.
API validation: When using the backend validation API with multiple countries (array input), the `follow_upward` parameter is automatically ignored, as it requires a single selection to determine parent-subdivision relationships.
By default, when your plan includes extended subdivisions, the widget will show the extended translations (50+ languages). Add `prefer_official=1` to the script URL or set `preferOfficialSubdivisions: true` in `window.CountriesDBConfig` to globally prefer the official ISO list.
Official preference only takes effect when your plan has extended subdivisions available. If your plan only includes official subdivisions (or none), the flag is ignored and the appropriate default is used automatically.
The `show_subdivision_type` parameter controls whether subdivision types (like "State", "Province", "Region", etc.) are displayed in subdivision names. Add `show_subdivision_type=0` to the script URL or set `showSubdivisionType: false` in `window.CountriesDBConfig`. By default, this is enabled (true), showing names like "California (State)". When disabled (false), it shows only the subdivision name like "California". This is useful for applications that want cleaner subdivision names without type indicators.
Note: This parameter only works for Official ISO subdivisions. For extended subdivision translations, the type is always included in the translation itself.
The `allow_parent_selection` parameter controls whether users can select parent subdivisions in multi-level subdivision hierarchies. Add `allow_parent_selection=1` to the script URL or set `allowParentSelection: true` in `window.CountriesDBConfig`. By default, this is disabled (false), meaning users can only select the most nested subdivisions (the most specific ones). When enabled (true), users can also select parent subdivisions, which are more general administrative levels.
Note: This parameter is particularly useful for countries with complex administrative hierarchies where you want to allow selection at different levels of specificity.
The `auto_init` parameter controls when the widget automatically initializes and loads country/subdivision data. Add `auto_init=0` to the script URL or set `autoInit: false` in `window.CountriesDBConfig`. By default, this is enabled (true), meaning the widget loads immediately when the script is included. When disabled (false), you have full control over when to initialize the widget by calling `window.CountriesWidgetLoad()`, allowing you to delay loading until specific conditions are met (like user authentication, form validation, or other prerequisites).
Enable this option to display ISO short names for countries (e.g., "United States of America") instead of localized names (e.g., "Estados Unidos" in Spanish). Add `iso_country_names=1` to the script URL or set `isoCountryNames: true` in `window.CountriesDBConfig`. This only affects country fields; subdivision fields remain unchanged. Sorting uses the displayed names.
Prefer specific romanization systems for official subdivisions. Provide a comma-separated list (e.g., "un,bgn"). When a preferred system is not available for a country, the widget falls back to the default official name.
Real example (Belarus): BY provides UN and GOST/UN variants for the same subdivisions. For example, BY-BR has "Bresckaja voblasฤ" (UN X/6 2012) and "Brestskaja oblast'" (GOST 1983 = UN V/18 1987). With "un" you will see the UN form; with "gost,un" the GOST form is preferred. Open the live example below and select Belarus to see the difference.
You don't need to specify a default. If none of your listed systems are available, the default official name is used automatically.
Note: This option is ignored when extended subdivisions are active.
Display local variant names for official subdivisions when available. Local variants are alternative names that may be more familiar to users in certain regions or contexts.
Real example (Egypt): EG subdivisions have both official names and local variants. For example, "Al Qฤhirah" has the local variant "Cairo", "Al Iskandarฤซyah" has "Alexandria", and "Al Jฤซzah" has "Giza". When prefer_local_variant is enabled, the widget will display these familiar names instead of the official transliterated names.
This option works alongside romanization preference: romanization system is selected first, then local variant is preferred if available. If no local variant exists for the selected romanization system, the regular name is used. This option only applies to official subdivisions (is_extended = 0), not extended ones.
Note: This option is ignored when extended subdivisions are active.
Customize country and subdivision names on-the-fly using JavaScript callback functions. Name filters override all other name sources (romanization, local variant, language preferences), giving you complete control over displayed names.
Use separate filters for countries and subdivisions. Each filter receives the original name, language information from the server, and the full item object. For subdivisions, the filter also receives the country code extracted from the subdivision code.
When name filters are used, the widget automatically re-sorts the options using Unicode-aware, case-insensitive, accent-sensitive sorting based on the detected language from the server. This ensures proper sorting even after names are customized (e.g., "ฤ " sorts after "a" but before "b").
Filter functions can return a custom name (string), use the original name (null/undefined), or completely remove the item from the list (false).