11import { NextConfig } from "config/index.js" ;
22import type { DomainLocale , i18nConfig } from "types/next-types" ;
3- import type { InternalEvent } from "types/open-next" ;
3+ import type { InternalEvent , InternalResult } from "types/open-next" ;
44
55import { debug } from "../../../adapters/logger.js" ;
66import { acceptLanguage } from "./accept-header" ;
7+ import { emptyReadableStream } from "utils/stream.js" ;
78
89function isLocalizedPath ( path : string ) : boolean {
910 return (
@@ -21,15 +22,15 @@ function getLocaleFromCookie(cookies: Record<string, string>) {
2122}
2223
2324// 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 ) {
25+ export function detectDomainLocale ( {
26+ hostname,
27+ detectedLocale ,
28+ } : {
29+ hostname ?: string ;
30+ detectedLocale ?: string ;
31+ } ) : DomainLocale | undefined {
32+ const i18n = NextConfig . i18n ;
33+ if ( ! i18n || i18n . localeDetection === false || ! i18n . domains ) {
3334 return ;
3435 }
3536 for ( const item of i18n . domains ) {
@@ -64,7 +65,9 @@ export function detectLocale(
6465 defaultLocale : i18n . defaultLocale ,
6566 } ) ;
6667
67- const domainLocale = detectDomainLocale ( internalEvent . headers . host , i18n ) ;
68+ const domainLocale = detectDomainLocale ( {
69+ hostname : internalEvent . headers . host ,
70+ } ) ;
6871
6972 return (
7073 domainLocale ?. defaultLocale ??
@@ -82,17 +85,70 @@ export function localizePath(internalEvent: InternalEvent): string {
8285 if ( isLocalizedPath ( internalEvent . rawPath ) ) {
8386 return internalEvent . rawPath ;
8487 }
88+
89+ const detectedLocale = detectLocale ( internalEvent , i18n ) ;
90+
91+ return `/${ detectedLocale } ${ internalEvent . rawPath } ` ;
92+ }
93+
94+ export function handleLocaleRedirect (
95+ internalEvent : InternalEvent ,
96+ ) : false | InternalResult {
97+ const i18n = NextConfig . i18n ;
98+ if (
99+ ! i18n ||
100+ i18n . localeDetection === false ||
101+ internalEvent . rawPath !== "/"
102+ ) {
103+ return false ;
104+ }
85105 const preferredLocale = acceptLanguage (
86106 internalEvent . headers [ "accept-language" ] ,
87107 i18n ?. locales ,
88108 ) ;
89109
90110 const detectedLocale = detectLocale ( internalEvent , i18n ) ;
91111
92- // not entirely sure if we should do that or not here
93- if ( preferredLocale && preferredLocale !== detectedLocale ) {
94- return `/${ preferredLocale } ${ internalEvent . rawPath } ` ;
112+ const domainLocale = detectDomainLocale ( {
113+ hostname : internalEvent . headers . host ,
114+ } ) ;
115+ const preferredDomain = detectDomainLocale ( {
116+ detectedLocale : preferredLocale ?. toLowerCase ( ) ,
117+ } ) ;
118+
119+ if ( domainLocale && preferredDomain ) {
120+ const isPDomain = preferredDomain . domain === domainLocale . domain ;
121+ const isPLocale = preferredDomain . defaultLocale === preferredLocale ;
122+ if ( ! isPDomain || ! isPLocale ) {
123+ const scheme = `http${ preferredDomain . http ? "" : "s" } ` ;
124+ const rlocale = isPLocale ? "" : preferredLocale ;
125+ return {
126+ type : "core" ,
127+ statusCode : 307 ,
128+ headers : {
129+ Location : `${ scheme } ://${ preferredDomain . domain } /${ rlocale } ` ,
130+ } ,
131+ body : emptyReadableStream ( ) ,
132+ isBase64Encoded : false ,
133+ } ;
134+ }
95135 }
96136
97- return `/${ detectedLocale } ${ internalEvent . rawPath } ` ;
137+ const defaultLocale = domainLocale ?. defaultLocale ?? i18n . defaultLocale ;
138+
139+ if ( detectedLocale . toLowerCase ( ) !== defaultLocale . toLowerCase ( ) ) {
140+ return {
141+ type : "core" ,
142+ statusCode : 307 ,
143+ headers : {
144+ Location : new URL (
145+ `${ NextConfig . basePath || "" } /${ detectedLocale } ` ,
146+ internalEvent . url ,
147+ ) . href ,
148+ } ,
149+ body : emptyReadableStream ( ) ,
150+ isBase64Encoded : false ,
151+ } ;
152+ }
153+ return false ;
98154}
0 commit comments