A country search box is a substring problem. Someone types uni and expects United Kingdom, United States, and the Emirates — and they'll also get Tunisia, because that's how substrings work.
The endpoint
/name/{query} matches anywhere in the name, case-insensitively:
curl https://countries.dev/name/uniWiring it up
Debounce the input so you're not firing a request per keystroke, ask for only the fields a result row needs, and treat the empty case correctly — the endpoint returns 404 when nothing matches, not an empty array:
async function search(query) {
const res = await fetch(
`https://countries.dev/name/${encodeURIComponent(query)}?fields=name,alpha2Code,flag`
);
return res.ok ? res.json() : []; // 404 = no matches
}
input.addEventListener("input", debounce(async (e) => {
const q = e.target.value.trim();
render(q ? await search(q) : []);
}, 200));Two things worth getting right: encodeURIComponent, so a multi-word query like "south k" doesn't break the URL, and reading a 404 as "no results" instead of throwing.
Written by
Dov Azencot
At
Tue Jun 23 2026