Countries
Guidance on displaying country information, flags, and integrating with the Kaharagian countries collection API.
Flag Display Examples
Country flags from the country_flags collection are displayed with a 4:3 aspect ratio, grey border, and no rounded corners.
Showing 204 countries from the Citadel API
Why the grey border?
Flags with white backgrounds (like Japan) need a visible border to separate them from the page background. The grey border ensures all flags display consistently.
Countries Collection API
The country_flags collection provides standardised country data including names, ISO codes, and flag images for use across government services.
API Endpoint
GET /api/countries
// Response
{
"data": [
{
"id": 1,
"name": "United Kingdom",
"iso_alpha_2": "GB",
"iso_alpha_3": "GBR",
"flag_url": "https://citadel.kaharagia.org/storage/uploads/gb-xxx.svg"
},
{
"id": 2,
"name": "Kaharagia",
"iso_alpha_2": "KH",
"iso_alpha_3": "KHR",
"flag_url": "https://citadel.kaharagia.org/storage/uploads/kh-xxx.svg"
},
// ...
],
"source": "citadel",
"count": 204
}Fetching Countries
// JavaScript example
const response = await fetch('/api/countries');
const { data: countries } = await response.json();
// Filter or search
const filtered = countries.filter(c =>
c.name.toLowerCase().includes(searchTerm.toLowerCase())
);Displaying Country Flags
When displaying flags from the country_flags collection, follow these guidelines to ensure consistency across all government services.
Aspect Ratio
Country flags in the collection use a 4:3 aspect ratio. This differs from Kaharagian national flags which use 3:2. Always maintain the 4:3 ratio when displaying country flags.
Important
Country flags from the country_flags collection use 4:3 aspect ratio. Do not confuse with Kaharagian national flags which use 3:2.
Border and Radius
All country flags must be displayed with:
- Border: 1px solid grey (
var(--color-gray-300)) - Border radius: 0 (no rounded corners)
The grey border ensures flags with white backgrounds (e.g., Japan, South Korea) remain visible against light page backgrounds.
CSS Implementation
.country-flag {
/* 4:3 aspect ratio */
aspect-ratio: 4 / 3;
width: 100%;
max-width: 120px;
height: auto;
/* Grey border, no radius */
border: 1px solid var(--color-gray-300);
border-radius: 0;
/* Ensure flag fills container */
object-fit: cover;
}
/* Small flag variant (for inline use) */
.country-flag-sm {
aspect-ratio: 4 / 3;
width: 24px;
height: auto;
border: 1px solid var(--color-gray-300);
border-radius: 0;
object-fit: cover;
vertical-align: middle;
}
/* Medium flag variant */
.country-flag-md {
aspect-ratio: 4 / 3;
width: 48px;
height: auto;
border: 1px solid var(--color-gray-300);
border-radius: 0;
object-fit: cover;
}
/* Large flag variant */
.country-flag-lg {
aspect-ratio: 4 / 3;
width: 120px;
height: auto;
border: 1px solid var(--color-gray-300);
border-radius: 0;
object-fit: cover;
}Example Usage
Flag with Country Name
<div class="country-item">
<img
src={country.flag_url}
alt="United Kingdom flag"
class="country-flag-md"
>
<span>United Kingdom</span>
</div>In a Select Dropdown
<div class="form-group">
<label class="form-label" for="country">Country of birth</label>
<select class="form-select" id="country" name="country">
<option value="">Select a country</option>
<!-- Populated from countries API -->
{countries.map(c => (
<option value={c.iso_alpha_2}>{c.name}</option>
))}
</select>
</div>Country List with Flags
United Kingdom
France
Germany
Japan
<ul class="country-list">
{countries.map(country => (
<li class="country-list-item">
<img
src={country.flag_url}
alt={`${country.name} flag`}
class="country-flag-sm"
>
<span>{country.name}</span>
</li>
))}
</ul>Autocomplete Integration
For forms requiring country selection, use the Autocomplete component with the countries collection for a better user experience.
// React example with Autocomplete
import Autocomplete from '@/components/Autocomplete';
const [countries, setCountries] = useState([]);
useEffect(() => {
fetch('/api/countries')
.then(res => res.json())
.then(data => setCountries(data.data));
}, []);
<Autocomplete
label="Country of birth"
name="country"
options={countries.map(c => ({
value: c.iso_alpha_2,
label: c.name,
icon: c.flag_url
}))}
placeholder="Start typing a country name..."
/>Design Specifications
| Property | Value | Notes |
|---|---|---|
| Aspect ratio | 4:3 | Different from Kaharagian flags (3:2) |
| Border | 1px solid var(--color-gray-300) | Ensures visibility on light backgrounds |
| Border radius | 0 | No rounded corners |
| Small size | 24px width | For inline use with text |
| Medium size | 48px width | For list items and cards |
| Large size | 120px width | For detail views |
Accessibility
- Always include descriptive alt text:
"[Country name] flag" - Never use flags as the only means of identifying a country
- Pair flags with text labels in all interactive elements
- Ensure sufficient colour contrast with surrounding elements
Common Patterns
Country Selection in Forms
For most forms, a standard select dropdown populated from the collection is sufficient. Use autocomplete for long lists or when users may not know the exact country name.
Nationality Display
When displaying a user's nationality, show both the flag and country name:
<div class="nationality-display">
<img
src={country.flag_url}
alt="Kaharagia flag"
class="country-flag-sm"
>
<span>{country.demonym}</span>
</div>Multiple Nationalities
When a user has multiple nationalities, display them as a list:
Cambodian
British
<ul class="nationality-list">
{nationalities.map(country => (
<li>
<img src={country.flag_url} alt={`${country.name} flag`} class="country-flag-sm">
{country.demonym}
</li>
))}
</ul>CSS Classes Reference
/* Country flag base */
.country-flag { }
/* Size variants */
.country-flag-sm { } /* 24px width */
.country-flag-md { } /* 48px width */
.country-flag-lg { } /* 120px width */
/* Container patterns */
.country-item { } /* Flag + name inline */
.country-list { } /* List of countries */
.country-list-item { } /* Single list item */