chore: get locale domains working in dev

finxol.io 95dc5b8e 35c372d7

verified
+17
Caddyfile
··· 1 + # French locale (default) 2 + http://fr.traefik.me { 3 + reverse_proxy 127.0.0.1:4321 { 4 + header_up Host fr.traefik.me 5 + header_up X-Forwarded-Host fr.traefik.me 6 + header_up X-Forwarded-Proto http 7 + } 8 + } 9 + 10 + # English locale 11 + http://en.traefik.me { 12 + reverse_proxy 127.0.0.1:4321 { 13 + header_up Host en.traefik.me 14 + header_up X-Forwarded-Host en.traefik.me 15 + header_up X-Forwarded-Proto http 16 + } 17 + }
+8 -1
astro.config.mjs
··· 7 7 8 8 // https://astro.build/config 9 9 export default defineConfig({ 10 - site: "https://next.colinozanne.fr", 10 + site: config.domains[config.defaultLocale], 11 11 output: "server", 12 12 adapter: deno(), 13 13 integrations: [preact(), icon()], ··· 20 20 prefixDefaultLocale: false, 21 21 }, 22 22 domains: config.domains, 23 + }, 24 + vite: { 25 + server: { 26 + allowedHosts: Object.values(config.domains).map((host) => 27 + host.replace(/^https?:\/\//, ""), 28 + ), 29 + }, 23 30 }, 24 31 });
+1 -1
package.json
··· 3 3 "type": "module", 4 4 "version": "0.0.1", 5 5 "scripts": { 6 - "dev": "astro dev", 6 + "dev": "DENO_ENV=development astro dev", 7 7 "build": "astro build", 8 8 "preview": "deno run --allow-net --allow-read --allow-env ./dist/server/entry.mjs", 9 9 "astro": "astro"
+11 -4
src/config.ts
··· 1 + export const isDev = Deno.env.get("DENO_ENV") === "development"; 2 + 1 3 export const config = { 2 4 defaultLocale: "fr", 3 5 locales: ["fr", "en"], 4 - domains: { 5 - fr: "https://next.colinozanne.fr", 6 - en: "https://next.colinozanne.co.uk", 7 - }, 6 + domains: isDev 7 + ? { 8 + fr: "http://fr.traefik.me", 9 + en: "http://en.traefik.me", 10 + } 11 + : { 12 + fr: "https://next.colinozanne.fr", 13 + en: "https://next.colinozanne.co.uk", 14 + }, 8 15 } as const;
+47
src/middleware.ts
··· 1 + import { defineMiddleware } from "astro:middleware"; 2 + import { config, isDev } from "./config.ts"; 3 + 4 + export const onRequest = isDev && defineMiddleware((context, next) => { 5 + const { url } = context; 6 + 7 + // Get the locale from the domain 8 + const host = context.request.headers.get("x-forwarded-host") || 9 + context.request.headers.get("host") || 10 + url.host; 11 + 12 + // Find which locale this domain corresponds to 13 + let domainLocale: string | undefined; 14 + for (const [locale, domain] of Object.entries(config.domains)) { 15 + const domainHost = new URL(domain as string).host; 16 + if (host === domainHost) { 17 + domainLocale = locale; 18 + break; 19 + } 20 + } 21 + 22 + // If we're on a domain-mapped locale and the path doesn't start with the locale prefix, 23 + // internally rewrite to add the prefix 24 + if (domainLocale && url.pathname === "/") { 25 + // Rewrite / to /{locale}/ 26 + return context.rewrite(`/${domainLocale}/`); 27 + } 28 + 29 + // For other paths without locale prefix, also rewrite 30 + if ( 31 + domainLocale && !url.pathname.startsWith(`/${domainLocale}/`) && 32 + !url.pathname.startsWith(`/${domainLocale}`) 33 + ) { 34 + // Check if the path starts with any other locale 35 + const startsWithOtherLocale = config.locales.some( 36 + (l: string) => 37 + l !== domainLocale && 38 + (url.pathname.startsWith(`/${l}/`) || url.pathname === `/${l}`), 39 + ); 40 + 41 + if (!startsWithOtherLocale) { 42 + return context.rewrite(`/${domainLocale}${url.pathname}`); 43 + } 44 + } 45 + 46 + return next(); 47 + });