@geoicons/vue
v1.4.1
Published
799 geographic map SVG icons (255 countries & territories + 167 world areas + 377 subdivisions) as tree-shakable Vue 3 components — control weight and fill with strokeWidth and native SVG attributes, themed via currentColor.
Downloads
96
Maintainers
Readme
@geoicons/vue
799 geographic map icons as tree-shakable Vue 3 components - 255 countries + 167 areas (continents, regions, blocs, landforms) + 377 subdivisions (states, provinces, parishes). Fully customizable stroke width and color via props; icons inherit currentColor by default, so they adapt to your text color out of the box.
⚖️ Dual-licensed: GPLv3 or Commercial. Free to use in open-source projects under GPL-3.0-only (your project must also be GPL). Building something closed-source / proprietary / commercial? You need a commercial license → geoicons.io.
Install
npm install @geoicons/vueRequires Vue 3 (3.0+). On Vue 3.5+ it uses the built-in useId() for stable, SSR-safe, cross-app-unique ids; on 3.0–3.4 it falls back automatically to a per-instance id (only the optional aria-label <title> id relies on this).
Use
<script setup lang="ts">
import { UnitedStates, Japan } from '@geoicons/vue/countries';
import { Africa } from '@geoicons/vue/areas';
import { UsTexas } from '@geoicons/vue/subdivisions';
</script>
<template>
<UnitedStates :size="48" />
<Japan :size="48" :stroke-width="0.5" class="text-blue-600" />
<Africa :size="48" />
<UsTexas :size="48" />
</template>No config, no CSS import. Icons inherit currentColor by default.
Props
| Prop | Type | Default | Notes |
| -------------- | ------------------ | ---------------- | -------------------------------------------------------------- |
| size | number \| string | 24 | Convenience prop - sets both width and height |
| strokeWidth | number | 1 | Stroke width in SVG units; scale up with icon size |
| stroke | string | 'currentColor' | Native SVG attr - outline color; any CSS color value |
| fill | string | 'none' | Native SVG attr - pass fill="currentColor" for a solid shape |
| aria-label | string | - | Makes the icon meaningful to screen readers (see below) |
| class | string | - | Forwarded to <svg> |
| …rest | SVG attributes | - | style, @click, data-*, etc. - forwarded via attr fallthrough |
Only size and strokeWidth are declared props; stroke, fill, and everything else fall through straight to the underlying <svg>.
Scaling stroke width
As icons grow, the default stroke width of 1 may look too thin:
<Us :size="24" /> <!-- 1px stroke - default -->
<Us :size="48" :stroke-width="1.5" /> <!-- scale up proportionally -->
<Us :size="96" :stroke-width="2" />Custom color
<Us stroke="#3b82f6" /> <!-- hex -->
<Us stroke="oklch(60% .2 250)" /> <!-- any CSS color -->
<Us class="text-red-500" /> <!-- or inherit via currentColor -->Filled shape
Pass fill for a solid icon. The same-color outline keeps it solid, so
stroke-width="0" is optional - add it for a bare silhouette or a different
fill color:
<Us fill="currentColor" />
<Us fill="#3b82f6" :stroke-width="0" />Naming & imports
Icons are named from ISO 3166-1 alpha-2 codes (PascalCase): us → Us, jp → Jp, au-mainland → AuMainland. Every country also ships a full-name alias — UnitedStates for Us, Bhutan for Bt, SouthKorea for Kr — pointing at the same component, so import whichever reads better; tree-shaking bundles exactly one either way. Areas use slug PascalCase: africa → Africa, european-union-eu → EuropeanUnion. Subdivisions are the parent country code plus the subdivision name: us-texas → UsTexas, ca-ontario → CaOntario, jm-kingston → JmKingston.
// Country icons - by ISO code or full name (same component):
import { Us, Jp, Fr } from '@geoicons/vue/countries';
import { UnitedStates, Japan, France } from '@geoicons/vue/countries';
// Areas - continents, regions, blocs, landforms:
import { Africa, Asia, Europe, EuropeanUnion } from '@geoicons/vue/areas';
// Subdivisions - states, provinces, parishes:
import { UsTexas, CaOntario, JmKingston } from '@geoicons/vue/subdivisions';Accessibility
Icons default to decorative mode (aria-hidden="true"), which removes them from the accessibility tree when adjacent text already provides the label.
Pass aria-label to make an icon meaningful - it gets role="img", a <title> element, and aria-labelledby automatically:
<!-- Decorative - screen readers skip this -->
<Us :size="32" />
<!-- Meaningful - screen readers announce "United States" -->
<Us :size="32" aria-label="United States" />Tree-shaking
Each icon is an individual named export, so import { Us, Jp } ships only those two - never the whole catalog. The package is "sideEffects": false.
License & the GeoiconsLicense plugin
GeoIcons is dual-licensed: GPL-3.0-only or Commercial (see LICENSE and COMMERCIAL-LICENSE.md).
Icons render the same regardless of license, always - no watermark, no lock. If a project uses the icons without a confirmed license, a single console notice appears once per session (client-side) nudging toward GPLv3 compliance or a commercial key. The GeoiconsLicense plugin is the optional install that verifies your license fully offline (no network, no tracking); installing it with a valid commercial key or the GPL declaration silences the notice. It never changes how icons look.
Commercial use - install the plugin once with your purchased key:
import { createApp } from 'vue';
import { GeoiconsLicense } from '@geoicons/vue';
import App from './App.vue';
createApp(App)
.use(GeoiconsLicense, { licenseKey: import.meta.env.VITE_GEOICONS_KEY })
.mount('#app');Open-source use - declare GPL compliance to silence the notice:
app.use(GeoiconsLicense, { licenseKey: 'GPL-MY-PROJECT-IS-OPEN-SOURCE' });Building closed-source/commercial? Get a license at geoicons.io. Using these icons in a proprietary app without a commercial license violates the GPLv3.
Optional composable to read license status (reactive) in your own UI:
import { useGeoiconsLicense } from '@geoicons/vue';
const status = useGeoiconsLicense(); // Ref<'commercial' | 'gpl' | 'unverified' | 'invalid'>GeoIcons · geoicons.io · @geoicons/vue
