Skip to content

Commit 930a9b6

Browse files
authored
chore: rename enableLocaleDetection to localePathRedirect (#7857)
1 parent 8a60ba6 commit 930a9b6

File tree

15 files changed

+46
-69
lines changed

15 files changed

+46
-69
lines changed

packages/runtime/plugin-i18n/src/runtime/context.tsx

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export interface ModernI18nContextValue {
1010
// Plugin configuration for useModernI18n hook
1111
entryName?: string;
1212
languages?: string[];
13-
enableLocaleDetection?: boolean;
13+
localePathRedirect?: boolean;
1414
// Callback to update language in context
1515
updateLanguage?: (newLang: string) => void;
1616
}
@@ -33,12 +33,6 @@ export const ModernI18nProvider: FC<ModernI18nProviderProps> = ({
3333
);
3434
};
3535

36-
export interface UseModernI18nOptions {
37-
entryName?: string;
38-
languages?: string[];
39-
enableLocaleDetection?: boolean;
40-
}
41-
4236
export interface UseModernI18nReturn {
4337
language: string;
4438
changeLanguage: (newLang: string) => Promise<void>;
@@ -86,9 +80,7 @@ const useRouterHooks = () => {
8680
* @param options - Optional configuration to override context settings
8781
* @returns Object containing i18n functionality and utilities
8882
*/
89-
export const useModernI18n = (
90-
options: UseModernI18nOptions = {},
91-
): UseModernI18nReturn => {
83+
export const useModernI18n = (): UseModernI18nReturn => {
9284
const context = useContext(ModernI18nContext);
9385
if (!context) {
9486
throw new Error('useModernI18n must be used within a ModernI18nProvider');
@@ -97,19 +89,12 @@ export const useModernI18n = (
9789
const {
9890
language: contextLanguage,
9991
i18nInstance,
100-
entryName: contextEntryName,
101-
languages: contextLanguages,
102-
enableLocaleDetection: contextEnableLocaleDetection,
92+
entryName,
93+
languages,
94+
localePathRedirect,
10395
updateLanguage,
10496
} = context;
10597

106-
// Merge context options with passed options (passed options take precedence)
107-
const {
108-
entryName = contextEntryName,
109-
languages = contextLanguages || [],
110-
enableLocaleDetection = contextEnableLocaleDetection || false,
111-
} = options;
112-
11398
// Get router hooks safely
11499
const { navigate, location, hasRouter } = useRouterHooks();
115100

@@ -140,7 +125,7 @@ export const useModernI18n = (
140125

141126
// Update URL if locale detection is enabled, we're in browser, and router is available
142127
if (
143-
enableLocaleDetection &&
128+
localePathRedirect &&
144129
isBrowser() &&
145130
hasRouter &&
146131
navigate &&
@@ -151,19 +136,27 @@ export const useModernI18n = (
151136
const relativePath = currentPath.replace(entryPath, '');
152137

153138
// Build new path with updated language
154-
const newPath = buildLocalizedUrl(relativePath, newLang, languages);
139+
const newPath = buildLocalizedUrl(
140+
relativePath,
141+
newLang,
142+
languages || [],
143+
);
155144
const newUrl = entryPath + newPath + location.search + location.hash;
156145

157146
// Navigate to new URL
158147
navigate(newUrl, { replace: true });
159-
} else if (enableLocaleDetection && isBrowser() && !hasRouter) {
148+
} else if (localePathRedirect && isBrowser() && !hasRouter) {
160149
// Fallback: use window.history API when router is not available
161150
const currentPath = window.location.pathname;
162151
const entryPath = getEntryPath(entryName);
163152
const relativePath = currentPath.replace(entryPath, '');
164153

165154
// Build new path with updated language
166-
const newPath = buildLocalizedUrl(relativePath, newLang, languages);
155+
const newPath = buildLocalizedUrl(
156+
relativePath,
157+
newLang,
158+
languages || [],
159+
);
167160
const newUrl =
168161
entryPath + newPath + window.location.search + window.location.hash;
169162

@@ -183,7 +176,7 @@ export const useModernI18n = (
183176
[
184177
i18nInstance,
185178
updateLanguage,
186-
enableLocaleDetection,
179+
localePathRedirect,
187180
entryName,
188181
languages,
189182
hasRouter,
@@ -195,7 +188,7 @@ export const useModernI18n = (
195188
// Helper function to check if a language is supported
196189
const isLanguageSupported = useCallback(
197190
(lang: string) => {
198-
return languages.includes(lang);
191+
return languages?.includes(lang) || false;
199192
},
200193
[languages],
201194
);
@@ -204,7 +197,7 @@ export const useModernI18n = (
204197
language: currentLanguage,
205198
changeLanguage,
206199
i18nInstance,
207-
supportedLanguages: languages,
200+
supportedLanguages: languages || [],
208201
isLanguageSupported,
209202
};
210203
};

packages/runtime/plugin-i18n/src/runtime/index.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,19 @@ export const i18nPlugin = (options: I18nPluginOptions): RuntimePlugin => ({
2626
const {
2727
entryName,
2828
i18nInstance: userI18nInstance,
29-
changeLanguage,
3029
initOptions: userInitOptions,
3130
localeDetection,
3231
} = options;
3332
const {
34-
enable: enableLocaleDetection,
33+
localePathRedirect,
3534
languages = [],
3635
fallbackLanguage = 'en',
3736
} = localeDetection || {};
3837
let I18nextProvider: React.FunctionComponent<any> | null;
3938

4039
// Helper function to detect language from path
4140
const detectLanguageFromPath = (pathname: string) => {
42-
if (enableLocaleDetection) {
41+
if (localePathRedirect) {
4342
const relativePath = pathname.replace(getEntryPath(entryName), '');
4443
const detectedLang = getLanguageFromPath(
4544
relativePath,
@@ -61,7 +60,7 @@ export const i18nPlugin = (options: I18nPluginOptions): RuntimePlugin => ({
6160
}
6261
// Always detect language from path for consistency between SSR and client
6362
let initialLanguage = fallbackLanguage;
64-
if (enableLocaleDetection) {
63+
if (localePathRedirect) {
6564
if (isBrowser()) {
6665
// In browser, get from window.location
6766
initialLanguage = detectLanguageFromPath(window.location.pathname);
@@ -83,7 +82,7 @@ export const i18nPlugin = (options: I18nPluginOptions): RuntimePlugin => ({
8382
if (!isBrowser() && i18nInstance.cloneInstance) {
8483
i18nInstance = i18nInstance.cloneInstance();
8584
}
86-
if (enableLocaleDetection && i18nInstance.language !== initialLanguage) {
85+
if (localePathRedirect && i18nInstance.language !== initialLanguage) {
8786
// If instance is already initialized but language doesn't match the path, update it
8887
await i18nInstance.changeLanguage(initialLanguage);
8988
}
@@ -112,7 +111,7 @@ export const i18nPlugin = (options: I18nPluginOptions): RuntimePlugin => ({
112111

113112
// Initialize language from URL on mount (only when localeDetection is enabled)
114113
useEffect(() => {
115-
if (enableLocaleDetection) {
114+
if (localePathRedirect) {
116115
const currentPathname = getCurrentPathname();
117116
const currentLang = detectLanguageFromPath(currentPathname);
118117
if (currentLang !== lang) {
@@ -130,7 +129,7 @@ export const i18nPlugin = (options: I18nPluginOptions): RuntimePlugin => ({
130129
i18nInstance,
131130
entryName,
132131
languages,
133-
enableLocaleDetection,
132+
localePathRedirect,
134133
updateLanguage: setLang,
135134
};
136135

packages/runtime/plugin-i18n/src/server/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,15 @@ export const i18nServerPlugin = (options: I18nPluginOptions): ServerPlugin => ({
8181
return;
8282
}
8383
const {
84-
enable,
84+
localePathRedirect,
8585
languages = [],
8686
fallbackLanguage = 'en',
8787
} = getLocaleDetectionOptions(entryName, options.localeDetection);
8888
const originUrlPath = route.urlPath;
8989
const urlPath = originUrlPath.endsWith('/')
9090
? `${originUrlPath}*`
9191
: `${originUrlPath}/*`;
92-
if (enable) {
92+
if (localePathRedirect) {
9393
middlewares.push({
9494
name: 'i18n-server-middleware',
9595
path: urlPath,

packages/runtime/plugin-i18n/src/utils/config.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
* Base locale detection configuration for a single entry
33
*/
44
export interface BaseLocaleDetectionOptions {
5-
/** Whether locale detection is enabled for this entry */
6-
enable?: boolean;
5+
/** Whether to enable locale detection from path and automatic redirect */
6+
localePathRedirect?: boolean;
77
/** List of supported languages */
88
languages?: string[];
99
/** Fallback language when detection fails */
@@ -38,7 +38,15 @@ export const getLocaleDetectionOptions = (
3838

3939
if (hasEntryConfig(localeDetection)) {
4040
const { localeDetectionByEntry, ...globalConfig } = localeDetection;
41-
return localeDetectionByEntry?.[entryName] || globalConfig;
41+
const entryConfig = localeDetectionByEntry?.[entryName];
42+
// Merge entry-specific config with global config, entry config takes precedence
43+
if (entryConfig) {
44+
return {
45+
...globalConfig,
46+
...entryConfig,
47+
};
48+
}
49+
return globalConfig;
4250
}
4351

4452
return localeDetection;

pnpm-lock.yaml

Lines changed: 0 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/integration/i18n/app-csr/modern.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ export default defineConfig({
66
appTools(),
77
i18nPlugin({
88
localeDetection: {
9-
enable: true,
9+
localePathRedirect: true,
1010
languages: ['zh', 'en'],
1111
fallbackLanguage: 'en',
1212
localeDetectionByEntry: {
1313
index: {
14-
enable: false,
14+
localePathRedirect: false,
1515
},
1616
},
1717
},

tests/integration/i18n/app-csr/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
"react-i18next": "15.7.4",
1111
"@modern-js/runtime": "workspace:*",
1212
"@modern-js/plugin-i18n": "workspace:*",
13-
"i18next-browser-languagedetector": "8.2.0",
1413
"react": "^19.2.0",
1514
"react-dom": "^19.2.0"
1615
},

tests/integration/i18n/app-ssr/modern.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default defineConfig({
99
appTools(),
1010
i18nPlugin({
1111
localeDetection: {
12-
enable: true,
12+
localePathRedirect: true,
1313
languages: ['zh', 'en'],
1414
fallbackLanguage: 'en',
1515
},

tests/integration/i18n/app-ssr/modern.ssg.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default defineConfig({
1818
appTools(),
1919
i18nPlugin({
2020
localeDetection: {
21-
enable: true,
21+
localePathRedirect: true,
2222
languages: ['zh', 'en'],
2323
fallbackLanguage: 'en',
2424
},

tests/integration/i18n/app-ssr/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
"react-i18next": "15.7.4",
1212
"@modern-js/runtime": "workspace:*",
1313
"@modern-js/plugin-i18n": "workspace:*",
14-
"i18next-browser-languagedetector": "8.2.0",
1514
"react": "^19.2.0",
1615
"react-dom": "^19.2.0"
1716
},

0 commit comments

Comments
 (0)