+17
Caddyfile
+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
+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
+1
-1
package.json
+11
-4
src/config.ts
+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
+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
+
});