One glanceable card that tells you exactly where you are.
A small, offline-capable location utility, built as a Next.js app. It reads your GPS position, names the place you're standing in, and lays out the full administrative hierarchy — country down to the finest named area your fix can support — alongside your raw coordinates and altitude. Tap anything to copy it; share the whole thing in one tap.
Built from the design Where Am I.dc.html.
- Live location via the browser Geolocation API (
enableHighAccuracy). - Place & hierarchy by reverse-geocoding with OpenStreetMap Nominatim — coarse → fine, adapting to each country's admin levels.
- Altitude from the device where available, otherwise from the Open-Meteo elevation model (labelled terrain model).
- Coordinates in decimal degrees (DD) or degrees-minutes-seconds (DMS) — tap to switch.
- Copy on tap for the place, any hierarchy level, coordinates, and altitude.
- Share via the native share sheet, falling back to clipboard.
The third-party lookups run through Next.js route handlers (/api/geocode,
/api/elevation) rather than straight from the browser. That lets the server
send Nominatim the identifying User-Agent its usage policy
asks for, cache responses, and keeps the app free of CORS surprises.
| State | Trigger |
|---|---|
| Acquiring | waiting for the first fix (also the server-rendered shell) |
| Live | good fix (accuracy ≤ 50 m) |
| Low accuracy | fix worse than 50 m — uncertain digits greyed, ladder trimmed, warning shown |
| Permission denied | user blocked location |
| Offline / cached | no network — shows the last known fix from localStorage |
| Error / unsupported | timeout, transient failure, or no Geolocation support |
Pull the card down to re-acquire.
Everything user-facing happens on your device. Coordinates are sent to Nominatim
and Open-Meteo (via this app's own API routes) only to resolve names and
elevation for the point you're at — no account, no tracking, nothing stored in a
database. The last fix is cached in your browser's localStorage so the app
still works offline.
Requires Node.js 18.18+.
npm install
npm run dev # http://localhost:3000Geolocation needs a secure context:
localhost is fine for development; for phone testing, deploy over HTTPS.
npm run build # production build
npm run start # serve the production buildDeploy anywhere that runs a Node server (Vercel, a container, etc.) — the API routes need a server runtime, so this is not a static export.
| Path | Role |
|---|---|
app/layout.tsx |
root layout, fonts, metadata & viewport |
app/page.tsx |
renders the client component |
app/globals.css |
design tokens & layout (from the source design) |
app/manifest.ts |
PWA manifest (metadata route) |
app/api/geocode/route.ts |
reverse-geocode proxy (Nominatim + User-Agent) |
app/api/elevation/route.ts |
elevation proxy (Open-Meteo) |
components/WhereAmI.tsx |
client component: state machine, geolocation, UI, interactions |
lib/format.ts |
DD/DMS, accuracy → ladder depth, share text |
lib/place.ts |
shape a Nominatim response into the place model |
lib/geo.ts |
client wrappers over the API routes |
lib/types.ts |
shared types |
public/sw.js |
service worker — runtime-caches the app shell for offline use |
app/icon.svg |
favicon (Next.js metadata icon convention) |
MIT — see LICENSE.