Pinned 2026 toolchains (Go 1.26, Rust 1.98/edition 2024, Python 3.14 + uv, Node 24, Zig 0.16, NixOS 26.05), postgres 18 / mongo 8, lockfiles built from, non-root runtimes, .dockerignore, per-project LICENSE, READMEs with the git.devai.io clone line, checkout@v7 CI. Security fixes in the legacy Rust APIs (any-password login, self-assigned admin, hard-coded JWT secret), JWT alg/exp/sub enforcement across the blog series, safe markdown links in the frontends, and many smaller bugs — every project was built, run and exercised end to end. Adds scripts/publish.sh + a CI publish job that splits every folder into its own repo at git.devai.io/templates/<folder>. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01128fhuZbgivaSJvtMf4s1G
2.2 KiB
country-explorer
Search any country and get a tidy fact card — flag, capital, region, population, languages and currencies — from the free countries.dev API. It's a lesson in pulling apart a rich, real-world JSON object.
Run
Get it: git clone https://git.devai.io/templates/country-explorer.git
Double-click index.html — it opens in your browser and works, as long as
you're online (it calls the countries API live). Nothing to install.
Or serve it like production:
docker compose up --build
Then open http://localhost:8080.
How it works
search(name) fetches https://countries.dev/name/<name> (no key needed). The
answer is an array of every country whose name contains your search, and the
page shows the first. One country is a rich object, and render() picks each
kind of field apart:
- plain values —
name,capital,regiongo straight intotextContent; - an image URL —
flags.svgbecomes the<img>'ssrc, so the flag loads from the address the API handed back; - a big number —
population.toLocaleString()turns125836021into125,836,021; - arrays of objects —
languagesandcurrenciesare mapped down to their.nameand joined with commas; - missing pieces — Antarctica has no capital and no currency, so
?.and|| "—"show a dash instead of crashing.
A 404 means no country matched and the page says so; "Loading…" and a friendly error cover the rest.
Try it: show every match as its own card, add each currency's symbol, or
show the nativeName of each language.
Layout
index.html the search form, a status line and a hidden fact card
app.js search() and render()
styles.css the look; follows your system's light or dark mode
Deploy
Push to your own GitHub repo and the shipped workflow
(.github/workflows/ci.yml) tests the compose stack, publishes the image to
GHCR, and — once you set the DEPLOY_HOST / DEPLOY_USER variables and
DEPLOY_KEY secret — deploys it to your server over ssh.
Part of devai.io — the APIs & Data track: fetch real data from the internet. Next up: ip-lookup.