Flag
The circular flag for a locale. Self-hosted, decorative, and silent when there is none.
vue
<script setup lang="ts">
import { flagFor, localeMeta } from '@core/i18n/localeMeta'
import SaFlag from '@shared/components/common/SaFlag.vue'
const LOCALES = Object.keys(localeMeta) as (keyof typeof localeMeta)[]
</script>
<template>
<ul class="grid gap-2 sm:grid-cols-3">
<li v-for="code in LOCALES" :key="code" class="flex items-center gap-2 text-sm">
<SaFlag :src="flagFor(code)" />
{{ localeMeta[code].label }}
</li>
</ul>
</template>Usage
src is a public/-relative URL, which flagFor(code) returns for a locale. The flags are self-hosted SVGs from circle-flags, so nothing is fetched from a third party.
It is a component rather than an <img> at each call site because three things have to hold everywhere:
- The alt text is empty. The language's name is always beside it, and alt text would make a screen reader say it twice.
- The box is fixed and does not shrink. The assets are 512 by 512 and would shift the row while loading.
- Nothing renders when
srcis absent, rather than a broken-image glyph.
A flag is not mirrored in a right-to-left layout. It is an image, not a directional glyph.
Examples
Sizes
size is a Tailwind size utility. The default, size-5, is 20 pixels, which reads right beside small text.
vue
<script setup lang="ts">
import { flagFor } from '@core/i18n/localeMeta'
import SaFlag from '@shared/components/common/SaFlag.vue'
</script>
<template>
<div class="flex items-center gap-4">
<SaFlag :src="flagFor('fr')" size="size-4" />
<SaFlag :src="flagFor('fr')" size="size-5" />
<SaFlag :src="flagFor('fr')" size="size-8" />
<SaFlag :src="flagFor('fr')" size="size-12" />
</div>
</template>No flag
flagFor returns undefined for a code it does not know, such as one left in a stale saved config. The component renders nothing.
vue
<script setup lang="ts">
import SaFlag from '@shared/components/common/SaFlag.vue'
</script>
<template>
<div class="flex items-center gap-2 text-sm">
<SaFlag :src="undefined" />
<span>No flag for this locale, and nothing is drawn</span>
</div>
</template>API
Source: src/shared/components/common/SaFlag.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | — | A public/-relative URL, usually from flagFor(code). Absent renders nothing. |
size | string | 'size-5' | A Tailwind size utility. |
Emits
None.
Slots
None.
Accessibility
- The image carries an empty
altandaria-hidden, because the language's name is always the text beside it. - It is
shrink-0in a fixed box, so a row does not reflow while the asset loads. - It loads lazily and decodes asynchronously, so a list of nine languages does not block the first paint.