From ecccaa14d325d8e0f4c4a87cdf18ce48cfccb62b Mon Sep 17 00:00:00 2001 From: Guido Jansen Date: Mon, 21 Sep 2026 22:47:19 +0200 Subject: [PATCH] Fix language auto-route loop on English-only pages Non-default-locale visitors (e.g. a Czech browser) hit an infinite /cs/cs/cs/... redirect via: switch to Czech, open the events page, click a guide (Hackathon). The client-side language auto-route in Base.astro fired on the English-only guide page (rendered lang="en" = the default locale) and sent the visitor to /cs/events/hackathon, which does not exist. The 404 page ALSO renders as the default locale, so the script re-ran there, re-prepended /cs, and looped forever. It affected every scope's non-default locale, not just .cz. Two fixes: - Idempotency guard: the script never prepends a locale onto a path that already begins with a built locale, so a default-locale page served under // (like the 404) can no longer stack prefixes. - autoRoute prop (default true), set false on the pages that exist only in the default locale (event guides, 404, offline, go-eu) so a non-default visitor is not bounced to a localized URL that was never built. Legitimate routing is unchanged: an English page still sends a Czech browser to its /cs/ equivalent. --- src/layouts/Base.astro | 28 +++++++++++++++++++++++----- src/layouts/Guide.astro | 2 +- src/pages/404.astro | 2 +- src/pages/go-eu.astro | 2 +- src/pages/offline.astro | 2 +- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro index 9993240..8c5b03b 100644 --- a/src/layouts/Base.astro +++ b/src/layouts/Base.astro @@ -24,9 +24,20 @@ interface Props { description?: string; /** Keep the page out of search engines (still reachable by URL). For share-only pages. */ noindex?: boolean; + /** Client-side language auto-routing sends a default-locale page to the visitor's preferred + * built locale. Turn OFF on pages that exist only in the default locale (event guides, 404, + * offline, go-eu): they have no localized counterpart, so redirecting a non-English visitor + * lands on a 404, and the 404 page re-running the script is what stacked /cs/cs/cs forever. */ + autoRoute?: boolean; } -const { title, lang = 'en', description: pageDescription, noindex = false } = Astro.props; +const { + title, + lang = 'en', + description: pageDescription, + noindex = false, + autoRoute = true, +} = Astro.props; const t = useTranslations(lang); // Every in-site link goes through localeHref: a two-way `lang === 'en' ? … : '/nl/…'` sent // every non-English visitor to Dutch, which made /fr/ a dead end on .be and put a Dutch @@ -126,7 +137,7 @@ const orgLd = { } } - {LOCALES.length > 1 && ( + {LOCALES.length > 1 && autoRoute && (