[ BLOG // 2026-07-01 // 2 MIN ]

Language detection by location — zero-server static site

How I added automatic language switching to my portfolio based on timezone and browser language — entirely client-side, no API, no flicker.

PROJECTS I18NASTROSTATIC SITEJAVASCRIPT

My portfolio is built with Astro and is fully static — no server-side rendering, no background API. The problem: when someone from Czechia opens the site, they get the English version. When someone from abroad opens it, they get Czech. Both are wrong.

The fix had to be simple — detect language automatically and redirect, but only once and without any visible flicker.

How it works

The entire detection runs as an inline <script> right in <head>, before the page renders:

  1. Manual choice always wins. If the user clicked the language switcher, the selection is stored in localStorage. This value always takes priority — we never override it.

  2. One-shot redirect. sessionStorage tracks whether we already redirected in this session. If yes, we do nothing — no ping-pong loops.

  3. Detection via timezone. Intl.DateTimeFormat().resolvedOptions().timeZone gives us a free geo hint — if the user is in Prague, they probably want Czech. No geolocation API, no third-party service, zero cost.

  4. Fallback: browser language. If not in Prague, we check navigator.languages. If it contains “cs”, we treat the user as Czech.

  5. Redirect via location.replace(). Not assign()replace() doesn’t add a history entry, so the back button works correctly.

Why this approach

The alternative would be server-side detection (Cloudflare Workers, nginx rules, etc.), but that means extra config, another thing that can break, and potential SEO issues if the redirect isn’t done properly.

This solution:

  • Costs $0 — no API, no infrastructure
  • Runs before paint — no content flash in the wrong language
  • SEO-safe — bots don’t execute JS, so they see the original page normally
  • Respects the user — manual language choice is always sacred

The language switcher

When a user clicks the switcher, the choice is saved to localStorage under dragocz:lang alongside the standard redirect. On the next visit, auto-detect reads this value and keeps the user’s pick — even if they’re in a different country.

Three commits, clean result

Implementation ended up being three small commits: switcher saving the choice, inline detection script, and build verification. Under 50 lines of JavaScript total. No dependencies, no frameworks — just one script in the layout and one event listener on the switcher.

On a static site, this works surprisingly well. Clean, fast, zero maintenance.

// ALL_POSTS
BACK TO BLOG