How to add country icons to a React app
- react
- country-icons
- svg-icons
- tutorial
- geoicons
Geography is a blind spot in most icon libraries. They give you arrows and carets, not the shape of Japan or the outline of the EU, and the geographic packs that exist rarely fit a modern React bundle. GeoIcons does: 422 country and area icons, each its own named export. Adding one to a React app takes three steps: install the package, import the icon by its ISO code, and render it:
npm i @geoicons/reactimport { Us } from '@geoicons/react/countries';
export default function App() {
return <Us aria-label="United States" />;
}That is the whole path. Below: sizing, color, accessibility, and choosing an icon when you only know the country at runtime.
Key takeaways
- Install
@geoicons/react, then import each country by its ISO 3166 alpha-2 code in PascalCase:Us,Fr,Jp. - Icons are React components. Size them with
size, color them withcurrentColor, adjust weight withstrokeWidth. - Add
aria-labelwhen the icon carries meaning; leave it off (oraria-hidden) when it is decorative. - For a country chosen at runtime, build a small map of only the icons you import so the bundle stays tree-shakeable.
Step 1: Install the React package
Add the package to your project:
npm i @geoicons/reactIt has no runtime dependencies beyond React and ships as ES modules, so your bundler can tree-shake it. Tree-shaking is dead-code elimination: the bundler reads your static import statements at build time, keeps only the icons you name, and drops the rest. See how it keeps the bundle small.
Step 2: Import by ISO code
Each country is a named export keyed to its ISO 3166 alpha-2 code, PascalCased. If you know the code, you know the import name, so autocomplete does most of the work:
import { Us, Fr, Jp, De, Br } from '@geoicons/react/countries';Us is the United States, Fr is France, De is Germany, Br is Brazil. Importing from the /countries subpath keeps the module graph tight: you reach into the countries entry point instead of a root barrel that touches every category.
Step 3: Render and style
Each import is a plain React component. Drop it into your JSX and control it with props:
// Size in pixels, color through currentColor, weight through strokeWidth
<De size={48} />
<De size={48} stroke="#2563eb" />
<De size={48} strokeWidth={1.5} />
<De size={48} fill="currentColor" />Every icon takes the same props:
| Prop | What it does |
|---|---|
size | Width and height in pixels (number or string). |
stroke | Outline color. Defaults to currentColor. |
strokeWidth | Outline thickness. |
fill | Fill color. Set to currentColor for a solid icon. |
aria-label | Accessible name. Omit for a decorative icon. |
The same four, live:
Color comes from currentColor by default, so an icon follows the text color of whatever wraps it. Put one in a dark navbar and it turns light; put it on a colored button and it matches, with no per-icon color prop to thread through your tree.
Make it accessible
An icon is decorative until you give it a name. If the icon repeats a label that is already in the text, leave it decorative so screen readers skip it:
<li><Us aria-hidden="true" /> United States</li>If the icon is the only thing conveying the country, give it an aria-label so assistive tech can announce it:
<button aria-label="Select United States">
<Us aria-hidden="true" />
</button>Under the hood each icon namespaces its <title> id with React's useId(), so rendering the same country twice on one page never produces duplicate ids.
How do I render a country icon at runtime?
A country picker or a data table often knows the country only as a string at render time. We left GeoIcons without an <Icon name="us" /> lookup on purpose, because a string API forces the library to keep every icon. Build your own small map instead, listing only the countries you import:
import { Us, Fr, Jp } from '@geoicons/react/countries';
// You own this map, so it holds only the three icons you imported.
const byCode = { us: Us, fr: Fr, jp: Jp } as const;
export function CountryIcon({ code }: { code: keyof typeof byCode }) {
const Icon = byCode[code];
return <Icon aria-hidden="true" />;
}The bundler still sees three static imports at the top and prunes the other 419. You get a runtime lookup where you need one, without dragging in the whole catalog. For why the string-prop API breaks this, see why an icon library doesn't have to bloat your bundle.
Beyond countries: areas
The same import pattern covers 167 area icons: regions, continents, landforms, and groupings like the European Union. Areas use a PascalCase slug rather than an ISO code:
import { EuropeanUnionEu } from '@geoicons/react/areas';
<EuropeanUnionEu aria-label="European Union" />FAQ
- How do I add a country icon to a React app?
- Install @geoicons/react, import the country by its ISO 3166 alpha-2 code in PascalCase, and render it as a component. For example, import { Us } from '@geoicons/react/countries' gives you a <Us /> component you can size and color like any SVG.
- How do I show an icon for a country chosen at runtime?
- Import the countries you need and build a small object mapping codes to components, such as { us: Us, fr: Fr }. Look the component up by key at render time. This keeps the API tree-shakeable because you only import the icons the map lists.
Get started
Install the package and render your first country:
npm i @geoicons/reactimport { Us } from '@geoicons/react/countries';
export default function App() {
return <Us aria-label="United States" />;
}The full prop and import reference lives in the GeoIcons API reference, or browse all 422 icons to find the ones you need. New to the library? Start with the launch post.