Use the country-flag-icons package to show a small country flag in your product:
npm install country-flag-icons
By default flags use a 3:2 ratio. This is the primary format — use it in most scenarios: inline with text, lists, selects. Flags with a different ratio (e.g. 4:3) or from other sources are supported by overriding the --kbq-flag-aspect-ratio CSS variable.
Square flags live in a separate subpackage and are needed where the 3:2 format does not fit: avatar selectors, compact circles, dense grids.
Most 1:1 versions are a center crop of the 3:2 flag. For flags that lose meaning when cropped this way, the package ships dedicated square variants (e.g. EU and KR) — they are substituted automatically from the same subpackage.
Flags get a thin inset shadow (an inset outline) along the edge. Without it a flag blends into the background:
That is why the shadow color depends on the theme: in the light theme the shadow is dark, in the dark theme it lightens or is removed. The shadow is implemented as an inset box-shadow on a pseudo-element over the flag, and its color comes from a CSS variable that switches together with the theme.
A flag denotes a country or region, not a language. Do not use a flag to pick an interface language: one language is spoken in several countries (Spanish is not only Spain), and one country may have several languages.
First check availability via hasFlag(code) and do not render an empty gap:
import { hasFlag } from 'country-flag-icons';
hasFlag('RU'); // true
hasFlag('ZZ'); // false
Then it depends on the situation.
Unknown or invalid code. Show a neutral placeholder (a gray rectangle, square, circle or a globe icon). Empty space is acceptable only if it does not break the layout.
You need a non-country flag (organization, historical or disputed territory, federal subject). Do not add it to the country-flag-icons package. Add it to your internal set so that the way it is used does not change.
Supranational flags. The EU flag is available as a separate 1:1 version; for the rest (ASEAN, UN, etc.) create your own images in the project.
It is a real country, but the flag really is missing. This is unlikely — the ISO 3166-1 standard is fully covered — but first update the package version. If the flag is outdated or missing, open an issue or PR in the package repository, and temporarily use your own image in your project.
You need to show the flag at a large size. In the package the flags are redrawn and simplified for small sizes. To show them at a large size you need flags in their original detail — use a third-party package. In most sources flags are provided without redrawing.
If the flag carries meaning (for example, it is the only indicator of the selected country), pass a text caption:
<kbq-flag label="Germany"><img src="…/DE.svg" alt="" /></kbq-flag>
If there is already adjacent text (inline, option, block), the flag is decorative — mark it decorative so it is hidden from screen readers and does not duplicate the caption.
<kbq-flag decorative><img src="…/DE.svg" alt="" /></kbq-flag>
Germany
In short: a flag must always have a text alternative — either visible text next to it (then the flag is decorative), or a label caption for the screen reader (when there is no visible text). Only the third case is not allowed — when there is neither.
A gradient imitating folds is layered over the image; the flag is rounded and casts a shadow.
Use the 1:1 aspect ratio version.
Choose a flag size whose dimensions are multiples of a pixel — otherwise the image edges will be blurry.