Skip to content

Commit 8348e2a

Browse files
committed
fix locale middleware
1 parent 87b59e5 commit 8348e2a

File tree

3 files changed

+53
-3
lines changed

3 files changed

+53
-3
lines changed

packages/open-next/src/core/routing/i18n/index.ts

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { NextConfig } from "config/index.js";
2-
import type { i18nConfig } from "types/next-types";
2+
import type { DomainLocale, i18nConfig } from "types/next-types";
33
import type { InternalEvent } from "types/open-next";
44

55
import { debug } from "../../../adapters/logger.js";
@@ -20,6 +20,31 @@ function getLocaleFromCookie(cookies: Record<string, string>) {
2020
: undefined;
2121
}
2222

23+
// Inspired by https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/i18n/detect-domain-locale.ts
24+
export function detectDomainLocale(
25+
hostname: string,
26+
i18n: i18nConfig,
27+
detectedLocale?: string,
28+
): DomainLocale | undefined {
29+
if (i18n.localeDetection === false) {
30+
return;
31+
}
32+
if (!i18n.domains) {
33+
return;
34+
}
35+
for (const item of i18n.domains) {
36+
// We remove the port if present
37+
const domainHostname = item.domain.split(":", 1)[0].toLowerCase();
38+
if (
39+
hostname === domainHostname ||
40+
detectedLocale === item.defaultLocale.toLowerCase() ||
41+
item.locales?.some((locale) => detectedLocale === locale.toLowerCase())
42+
) {
43+
return item;
44+
}
45+
}
46+
}
47+
2348
export function detectLocale(
2449
internalEvent: InternalEvent,
2550
i18n: i18nConfig,
@@ -39,9 +64,14 @@ export function detectLocale(
3964
defaultLocale: i18n.defaultLocale,
4065
});
4166

42-
return cookiesLocale ?? preferredLocale ?? i18n.defaultLocale;
67+
const domainLocale = detectDomainLocale(internalEvent.headers.host, i18n);
4368

44-
// TODO: handle domain based locale detection
69+
return (
70+
domainLocale?.defaultLocale ??
71+
cookiesLocale ??
72+
preferredLocale ??
73+
i18n.defaultLocale
74+
);
4575
}
4676

4777
export function localizePath(internalEvent: InternalEvent): string {
@@ -52,6 +82,17 @@ export function localizePath(internalEvent: InternalEvent): string {
5282
if (isLocalizedPath(internalEvent.rawPath)) {
5383
return internalEvent.rawPath;
5484
}
85+
const preferredLocale = acceptLanguage(
86+
internalEvent.headers["accept-language"],
87+
i18n?.locales,
88+
);
89+
5590
const detectedLocale = detectLocale(internalEvent, i18n);
91+
92+
// not entirely sure if we should do that or not here
93+
if (preferredLocale && preferredLocale !== detectedLocale) {
94+
return `/${preferredLocale}${internalEvent.rawPath}`;
95+
}
96+
5697
return `/${detectedLocale}${internalEvent.rawPath}`;
5798
}

packages/open-next/src/core/routing/matcher.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ export function handleRedirects(
316316
redirects: RedirectDefinition[],
317317
): InternalResult | undefined {
318318
const trailingSlashRedirect = handleTrailingSlashRedirect(event);
319+
// TODO: handle locale redirects directly from here, at the moment it's next that will handle it
319320
if (trailingSlashRedirect) return trailingSlashRedirect;
320321
const { internalEvent, __rewrite } = handleRewrites(
321322
event,

packages/open-next/src/types/next-types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,17 @@ export type Header = {
6161
missing?: RouteHas[];
6262
};
6363

64+
export interface DomainLocale {
65+
defaultLocale: string;
66+
domain: string;
67+
http?: true;
68+
locales: readonly string[];
69+
}
70+
6471
export interface i18nConfig {
6572
locales: string[];
6673
defaultLocale: string;
74+
domains?: Array<DomainLocale>;
6775
localeDetection?: false;
6876
}
6977
export interface NextConfig {

0 commit comments

Comments
 (0)