diff --git a/apps/web/src/layouts/Layout.astro b/apps/web/src/layouts/Layout.astro index 638e8d6..2fe708d 100644 --- a/apps/web/src/layouts/Layout.astro +++ b/apps/web/src/layouts/Layout.astro @@ -7,7 +7,11 @@ interface Props { noindex?: boolean; } -// Astro.currentLocale tracks the language code matched by the URL even when the route is rewritten via fallback. +// Locale resolution order (Vercel rewrites lose the prefix from Astro's view, +// so we look in three places, top-priority first): +// 1. ?_locale= query param injected by the vercel.json rewrites +// 2. Astro.currentLocale — set when Astro's own i18n routing matches +// 3. URL prefix (covers local dev with the Astro server) const CURRENT_TO_LOCALE: Record = { en: "en", "pt-br": "pt-BR", @@ -16,8 +20,17 @@ const CURRENT_TO_LOCALE: Record = { es: "es", fr: "fr", }; -const cl = Astro.currentLocale; -const locale: Locale = (cl && CURRENT_TO_LOCALE[cl]) || "en"; + +function resolveLocale(): Locale { + const fromQuery = Astro.url.searchParams.get("_locale"); + if (fromQuery && CURRENT_TO_LOCALE[fromQuery]) return CURRENT_TO_LOCALE[fromQuery]; + const cl = Astro.currentLocale; + if (cl && CURRENT_TO_LOCALE[cl]) return CURRENT_TO_LOCALE[cl]; + const seg = Astro.url.pathname.split("/").filter(Boolean)[0]?.toLowerCase(); + if (seg && CURRENT_TO_LOCALE[seg]) return CURRENT_TO_LOCALE[seg]; + return "en"; +} +const locale = resolveLocale(); setLocale(locale); const { diff --git a/apps/web/vercel.json b/apps/web/vercel.json index 260d426..a761fcb 100644 --- a/apps/web/vercel.json +++ b/apps/web/vercel.json @@ -1,4 +1,15 @@ { + "rewrites": [ + { "source": "/pt-br", "destination": "/?_locale=pt-BR" }, + { "source": "/pt-br/", "destination": "/?_locale=pt-BR" }, + { "source": "/pt-br/:path*", "destination": "/:path*?_locale=pt-BR" }, + { "source": "/es", "destination": "/?_locale=es" }, + { "source": "/es/", "destination": "/?_locale=es" }, + { "source": "/es/:path*", "destination": "/:path*?_locale=es" }, + { "source": "/fr", "destination": "/?_locale=fr" }, + { "source": "/fr/", "destination": "/?_locale=fr" }, + { "source": "/fr/:path*", "destination": "/:path*?_locale=fr" } + ], "headers": [ { "source": "/(.*)",