@bleedingdev/modern-js-plugin-i18n 3.2.0-ultramodern.12 → 3.2.0-ultramodern.120
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +221 -11
- package/dist/cjs/cli/index.js +32 -5
- package/dist/cjs/runtime/I18nLink.js +17 -28
- package/dist/cjs/runtime/Link.js +252 -0
- package/dist/cjs/runtime/canonicalRoutes.js +18 -0
- package/dist/cjs/runtime/context.js +41 -10
- package/dist/cjs/runtime/hooks.js +17 -10
- package/dist/cjs/runtime/i18n/backend/config.js +9 -5
- package/dist/cjs/runtime/i18n/backend/defaults.js +15 -10
- package/dist/cjs/runtime/i18n/backend/defaults.node.js +16 -11
- package/dist/cjs/runtime/i18n/backend/index.js +9 -5
- package/dist/cjs/runtime/i18n/backend/middleware.common.js +9 -5
- package/dist/cjs/runtime/i18n/backend/middleware.js +9 -5
- package/dist/cjs/runtime/i18n/backend/middleware.node.js +13 -9
- package/dist/cjs/runtime/i18n/backend/sdk-backend.js +9 -5
- package/dist/cjs/runtime/i18n/backend/sdk-event.js +16 -11
- package/dist/cjs/runtime/i18n/detection/config.js +9 -5
- package/dist/cjs/runtime/i18n/detection/index.js +9 -5
- package/dist/cjs/runtime/i18n/detection/middleware.js +9 -5
- package/dist/cjs/runtime/i18n/detection/middleware.node.js +9 -5
- package/dist/cjs/runtime/i18n/index.js +9 -5
- package/dist/cjs/runtime/i18n/instance.js +17 -37
- package/dist/cjs/runtime/i18n/react-i18next.js +53 -0
- package/dist/cjs/runtime/i18n/utils.js +9 -17
- package/dist/cjs/runtime/index.js +50 -15
- package/dist/cjs/runtime/localizedPaths.js +105 -0
- package/dist/cjs/runtime/routerAdapter.js +167 -0
- package/dist/cjs/runtime/utils.js +87 -97
- package/dist/cjs/server/index.js +69 -13
- package/dist/cjs/shared/deepMerge.js +12 -8
- package/dist/cjs/shared/detection.js +9 -5
- package/dist/cjs/shared/localisedUrls.js +271 -0
- package/dist/cjs/shared/utils.js +15 -11
- package/dist/esm/cli/index.mjs +23 -0
- package/dist/esm/runtime/I18nLink.mjs +7 -22
- package/dist/esm/runtime/Link.mjs +209 -0
- package/dist/esm/runtime/canonicalRoutes.mjs +0 -0
- package/dist/esm/runtime/context.mjs +34 -7
- package/dist/esm/runtime/hooks.mjs +9 -6
- package/dist/esm/runtime/i18n/backend/defaults.mjs +1 -1
- package/dist/esm/runtime/i18n/backend/defaults.node.mjs +2 -2
- package/dist/esm/runtime/i18n/backend/middleware.node.mjs +3 -3
- package/dist/esm/runtime/i18n/instance.mjs +1 -19
- package/dist/esm/runtime/i18n/react-i18next.mjs +15 -0
- package/dist/esm/runtime/i18n/utils.mjs +0 -12
- package/dist/esm/runtime/index.mjs +23 -13
- package/dist/esm/runtime/localizedPaths.mjs +58 -0
- package/dist/esm/runtime/routerAdapter.mjs +129 -0
- package/dist/esm/runtime/utils.mjs +25 -30
- package/dist/esm/server/index.mjs +53 -7
- package/dist/esm/shared/localisedUrls.mjs +212 -0
- package/dist/esm-node/cli/index.mjs +23 -0
- package/dist/esm-node/runtime/I18nLink.mjs +7 -22
- package/dist/esm-node/runtime/Link.mjs +210 -0
- package/dist/esm-node/runtime/canonicalRoutes.mjs +1 -0
- package/dist/esm-node/runtime/context.mjs +34 -7
- package/dist/esm-node/runtime/hooks.mjs +9 -6
- package/dist/esm-node/runtime/i18n/backend/defaults.mjs +1 -1
- package/dist/esm-node/runtime/i18n/backend/defaults.node.mjs +2 -2
- package/dist/esm-node/runtime/i18n/backend/middleware.node.mjs +3 -3
- package/dist/esm-node/runtime/i18n/instance.mjs +1 -19
- package/dist/esm-node/runtime/i18n/react-i18next.mjs +16 -0
- package/dist/esm-node/runtime/i18n/utils.mjs +0 -12
- package/dist/esm-node/runtime/index.mjs +23 -13
- package/dist/esm-node/runtime/localizedPaths.mjs +59 -0
- package/dist/esm-node/runtime/routerAdapter.mjs +130 -0
- package/dist/esm-node/runtime/utils.mjs +25 -30
- package/dist/esm-node/server/index.mjs +53 -7
- package/dist/esm-node/shared/localisedUrls.mjs +213 -0
- package/dist/types/cli/index.d.ts +1 -0
- package/dist/types/runtime/I18nLink.d.ts +6 -0
- package/dist/types/runtime/Link.d.ts +56 -0
- package/dist/types/runtime/canonicalRoutes.d.ts +60 -0
- package/dist/types/runtime/context.d.ts +3 -0
- package/dist/types/runtime/hooks.d.ts +4 -2
- package/dist/types/runtime/i18n/backend/middleware.node.d.ts +1 -1
- package/dist/types/runtime/i18n/instance.d.ts +4 -6
- package/dist/types/runtime/i18n/react-i18next.d.ts +7 -0
- package/dist/types/runtime/index.d.ts +6 -1
- package/dist/types/runtime/localizedPaths.d.ts +39 -0
- package/dist/types/runtime/routerAdapter.d.ts +26 -0
- package/dist/types/runtime/types.d.ts +1 -1
- package/dist/types/runtime/utils.d.ts +13 -9
- package/dist/types/server/index.d.ts +6 -0
- package/dist/types/shared/localisedUrls.d.ts +21 -0
- package/dist/types/shared/type.d.ts +12 -0
- package/package.json +24 -28
- package/rstest.config.mts +39 -0
- package/src/cli/index.ts +44 -1
- package/src/runtime/I18nLink.tsx +14 -51
- package/src/runtime/Link.tsx +414 -0
- package/src/runtime/canonicalRoutes.ts +93 -0
- package/src/runtime/context.tsx +45 -7
- package/src/runtime/hooks.ts +13 -4
- package/src/runtime/i18n/backend/defaults.node.ts +2 -2
- package/src/runtime/i18n/backend/defaults.ts +3 -1
- package/src/runtime/i18n/backend/middleware.node.ts +1 -1
- package/src/runtime/i18n/instance.ts +3 -30
- package/src/runtime/i18n/react-i18next.ts +25 -0
- package/src/runtime/i18n/utils.ts +4 -26
- package/src/runtime/index.tsx +47 -12
- package/src/runtime/localizedPaths.ts +118 -0
- package/src/runtime/routerAdapter.tsx +333 -0
- package/src/runtime/types.ts +1 -1
- package/src/runtime/utils.ts +44 -37
- package/src/server/index.ts +117 -10
- package/src/shared/localisedUrls.ts +453 -0
- package/src/shared/type.ts +12 -0
- package/tests/i18nUtils.test.ts +52 -0
- package/tests/link.test.tsx +475 -0
- package/tests/linkTypes.test.ts +28 -0
- package/tests/localisedUrls.test.ts +312 -0
- package/tests/routerAdapter.test.tsx +452 -0
- package/tests/type-fixture/linkTypes.fixture.tsx +51 -0
- package/tests/type-fixture/tsconfig.json +15 -0
- package/dist/esm/rslib-runtime.mjs +0 -18
- package/dist/esm-node/rslib-runtime.mjs +0 -19
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type TInternalRuntimeContext } from '@modern-js/runtime/context';
|
|
2
|
+
import type { LocalisedUrlsMap } from '../shared/localisedUrls';
|
|
2
3
|
export declare const getPathname: (context: TInternalRuntimeContext) => string;
|
|
3
4
|
export declare const getEntryPath: () => string;
|
|
4
5
|
/**
|
|
@@ -9,14 +10,23 @@ export declare const getEntryPath: () => string;
|
|
|
9
10
|
* @returns The detected language or fallback language
|
|
10
11
|
*/
|
|
11
12
|
export declare const getLanguageFromPath: (pathname: string, languages: string[], fallbackLanguage: string) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Split a link target into its pathname, search and hash parts without
|
|
15
|
+
* relying on `new URL` (SSR-hot path; targets are relative).
|
|
16
|
+
*/
|
|
17
|
+
export declare const splitUrlTarget: (target: string) => {
|
|
18
|
+
pathname: string;
|
|
19
|
+
search: string;
|
|
20
|
+
hash: string;
|
|
21
|
+
};
|
|
12
22
|
/**
|
|
13
23
|
* Helper function to build localized URL
|
|
14
|
-
* @param
|
|
24
|
+
* @param target - The language-agnostic target; may include `?search` and `#hash`
|
|
15
25
|
* @param language - The target language
|
|
16
26
|
* @param languages - Array of supported languages
|
|
17
|
-
* @returns The localized URL path
|
|
27
|
+
* @returns The localized URL path with search and hash re-appended verbatim
|
|
18
28
|
*/
|
|
19
|
-
export declare const buildLocalizedUrl: (
|
|
29
|
+
export declare const buildLocalizedUrl: (target: string, language: string, languages: string[], localisedUrls?: boolean | LocalisedUrlsMap) => string;
|
|
20
30
|
export declare const detectLanguageFromPath: (pathname: string, languages: string[], localePathRedirect: boolean) => {
|
|
21
31
|
detected: boolean;
|
|
22
32
|
language?: string;
|
|
@@ -25,9 +35,3 @@ export declare const detectLanguageFromPath: (pathname: string, languages: strin
|
|
|
25
35
|
* Check if the given pathname should ignore automatic locale redirect
|
|
26
36
|
*/
|
|
27
37
|
export declare const shouldIgnoreRedirect: (pathname: string, languages: string[], ignoreRedirectRoutes?: string[] | ((pathname: string) => boolean)) => boolean;
|
|
28
|
-
export declare const useRouterHooks: () => {
|
|
29
|
-
navigate: any;
|
|
30
|
-
location: any;
|
|
31
|
-
params: any;
|
|
32
|
-
hasRouter: boolean;
|
|
33
|
-
};
|
|
@@ -4,5 +4,11 @@ export interface I18nPluginOptions {
|
|
|
4
4
|
localeDetection: LocaleDetectionOptions;
|
|
5
5
|
staticRoutePrefixes: string[];
|
|
6
6
|
}
|
|
7
|
+
type ApiPrefixInput = string | string[] | undefined;
|
|
8
|
+
export declare const collectApiPrefixes: (routes: Array<{
|
|
9
|
+
isApi?: boolean;
|
|
10
|
+
urlPath?: string;
|
|
11
|
+
}>, bffPrefix?: ApiPrefixInput) => string[];
|
|
12
|
+
export declare const matchesApiPrefix: (pathname: string, apiPrefixes: string[]) => boolean;
|
|
7
13
|
export declare const i18nServerPlugin: (options: I18nPluginOptions) => ServerPlugin;
|
|
8
14
|
export default i18nServerPlugin;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
|
|
2
|
+
export type LocalisedUrlPathMap = Record<string, string>;
|
|
3
|
+
export type LocalisedUrlsMap = Record<string, LocalisedUrlPathMap>;
|
|
4
|
+
export type LocalisedUrlsOption = boolean | LocalisedUrlsMap;
|
|
5
|
+
export interface ResolvedLocalisedUrlsConfig {
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
map: LocalisedUrlsMap;
|
|
8
|
+
}
|
|
9
|
+
export declare const normalisePathPattern: (path: string) => string;
|
|
10
|
+
export declare const resolveLocalisedUrlsConfig: (option: LocalisedUrlsOption | undefined) => ResolvedLocalisedUrlsConfig;
|
|
11
|
+
export declare const validateLocalisedUrls: (routes: (NestedRouteForCli | PageRoute)[], languages: string[], localisedUrls: LocalisedUrlsMap) => void;
|
|
12
|
+
export declare const applyLocalisedUrlsToRoutes: (routes: (NestedRouteForCli | PageRoute)[], languages: string[], localisedUrls: LocalisedUrlsMap) => (NestedRouteForCli | PageRoute)[];
|
|
13
|
+
export declare const matchPathPattern: (pathname: string, pattern: string) => Record<string, string> | null;
|
|
14
|
+
export declare const buildPathFromPattern: (pattern: string, params: Record<string, string>) => string;
|
|
15
|
+
export declare const resolveLocalisedPath: (pathname: string, targetLanguage: string, languages: string[], localisedUrls: LocalisedUrlsMap) => string;
|
|
16
|
+
/**
|
|
17
|
+
* Reverse-map a language-specific pathname (without language prefix) back to
|
|
18
|
+
* the canonical, language-agnostic path: localized slug patterns are matched
|
|
19
|
+
* against every language variant and rebuilt from the canonical map key.
|
|
20
|
+
*/
|
|
21
|
+
export declare const resolveCanonicalLocalisedPath: (pathname: string, languages: string[], localisedUrls: LocalisedUrlsMap) => string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { LanguageDetectorOptions, Resources } from '../runtime/i18n/instance';
|
|
2
|
+
import type { LocalisedUrlsOption } from './localisedUrls';
|
|
2
3
|
export interface BaseLocaleDetectionOptions {
|
|
3
4
|
localePathRedirect?: boolean;
|
|
4
5
|
i18nextDetector?: boolean;
|
|
@@ -6,6 +7,17 @@ export interface BaseLocaleDetectionOptions {
|
|
|
6
7
|
fallbackLanguage?: string;
|
|
7
8
|
detection?: LanguageDetectorOptions;
|
|
8
9
|
ignoreRedirectRoutes?: string[] | ((pathname: string) => boolean);
|
|
10
|
+
/**
|
|
11
|
+
* Enables localised pathnames in addition to the locale prefix.
|
|
12
|
+
*
|
|
13
|
+
* - `false`: keep only locale-prefix behavior (`/en/about`).
|
|
14
|
+
* - object: map canonical route paths to every configured language.
|
|
15
|
+
*
|
|
16
|
+
* Defaults to `true` when `localePathRedirect` is enabled, so route
|
|
17
|
+
* generation validates that every localisable route path has entries for all
|
|
18
|
+
* configured languages.
|
|
19
|
+
*/
|
|
20
|
+
localisedUrls?: LocalisedUrlsOption;
|
|
9
21
|
}
|
|
10
22
|
export interface LocaleDetectionOptions extends BaseLocaleDetectionOptions {
|
|
11
23
|
localeDetectionByEntry?: Record<string, BaseLocaleDetectionOptions>;
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"modern",
|
|
18
18
|
"modern.js"
|
|
19
19
|
],
|
|
20
|
-
"version": "3.2.0-ultramodern.
|
|
20
|
+
"version": "3.2.0-ultramodern.120",
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=20"
|
|
23
23
|
},
|
|
@@ -81,47 +81,43 @@
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@swc/helpers": "^0.5.
|
|
84
|
+
"@swc/helpers": "^0.5.23",
|
|
85
85
|
"i18next-browser-languagedetector": "^8.2.1",
|
|
86
86
|
"i18next-chained-backend": "^5.0.4",
|
|
87
|
-
"i18next-fs-backend": "^2.6.
|
|
87
|
+
"i18next-fs-backend": "^2.6.6",
|
|
88
88
|
"i18next-http-backend": "^4.0.0",
|
|
89
|
-
"i18next-http-middleware": "^3.9.
|
|
90
|
-
"
|
|
91
|
-
"@modern-js/
|
|
92
|
-
"@modern-js/runtime
|
|
93
|
-
"@modern-js/
|
|
94
|
-
"@modern-js/
|
|
95
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.2.0-ultramodern.
|
|
89
|
+
"i18next-http-middleware": "^3.9.7",
|
|
90
|
+
"react-i18next": "17.0.8",
|
|
91
|
+
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.2.0-ultramodern.120",
|
|
92
|
+
"@modern-js/server-runtime": "npm:@bleedingdev/modern-js-server-runtime@3.2.0-ultramodern.120",
|
|
93
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.2.0-ultramodern.120",
|
|
94
|
+
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.2.0-ultramodern.120",
|
|
95
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.2.0-ultramodern.120",
|
|
96
|
+
"@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.2.0-ultramodern.120"
|
|
96
97
|
},
|
|
97
98
|
"peerDependencies": {
|
|
98
|
-
"@modern-js/runtime": "3.2.0-ultramodern.
|
|
99
|
+
"@modern-js/runtime": "3.2.0-ultramodern.120",
|
|
99
100
|
"i18next": ">=25.7.4",
|
|
100
|
-
"react": "^19.2.
|
|
101
|
-
"react-dom": "^19.2.
|
|
102
|
-
"react-i18next": ">=15.7.4"
|
|
101
|
+
"react": "^19.2.7",
|
|
102
|
+
"react-dom": "^19.2.7"
|
|
103
103
|
},
|
|
104
104
|
"peerDependenciesMeta": {
|
|
105
105
|
"i18next": {
|
|
106
106
|
"optional": true
|
|
107
|
-
},
|
|
108
|
-
"react-i18next": {
|
|
109
|
-
"optional": true
|
|
110
107
|
}
|
|
111
108
|
},
|
|
112
109
|
"devDependencies": {
|
|
113
|
-
"@rslib/core": "0.
|
|
110
|
+
"@rslib/core": "0.22.0",
|
|
114
111
|
"@types/jest": "^30.0.0",
|
|
115
|
-
"@types/node": "^25.
|
|
116
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
117
|
-
"i18next": "26.
|
|
112
|
+
"@types/node": "^25.9.3",
|
|
113
|
+
"@typescript/native-preview": "7.0.0-dev.20260610.1",
|
|
114
|
+
"i18next": "26.3.1",
|
|
118
115
|
"jest": "^30.4.2",
|
|
119
|
-
"react": "^19.2.
|
|
120
|
-
"react-dom": "^19.2.
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"@modern-js/
|
|
124
|
-
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.2.0-ultramodern.12"
|
|
116
|
+
"react": "^19.2.7",
|
|
117
|
+
"react-dom": "^19.2.7",
|
|
118
|
+
"ts-jest": "^29.4.11",
|
|
119
|
+
"@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.2.0-ultramodern.120",
|
|
120
|
+
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.2.0-ultramodern.120"
|
|
125
121
|
},
|
|
126
122
|
"sideEffects": false,
|
|
127
123
|
"publishConfig": {
|
|
@@ -130,7 +126,7 @@
|
|
|
130
126
|
},
|
|
131
127
|
"scripts": {
|
|
132
128
|
"dev": "rslib build --watch",
|
|
133
|
-
"build": "rslib build",
|
|
129
|
+
"build": "rslib build && pnpm -w tsgo:dts \"$PWD\"",
|
|
134
130
|
"test": "rstest --passWithNoTests"
|
|
135
131
|
}
|
|
136
132
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import type { ProjectConfig } from '@rstest/core';
|
|
4
|
+
import { withTestPreset } from '@scripts/rstest-config';
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
|
|
8
|
+
const commonConfig: ProjectConfig = {
|
|
9
|
+
setupFiles: [resolve(__dirname, '../../../scripts/rstest-config/setup.ts')],
|
|
10
|
+
globals: true,
|
|
11
|
+
tools: {
|
|
12
|
+
swc: {
|
|
13
|
+
jsc: {
|
|
14
|
+
transform: {
|
|
15
|
+
react: {
|
|
16
|
+
runtime: 'automatic',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default {
|
|
25
|
+
projects: [
|
|
26
|
+
withTestPreset({
|
|
27
|
+
name: 'plugin-i18n-node',
|
|
28
|
+
testEnvironment: 'node',
|
|
29
|
+
include: ['tests/localisedUrls.test.ts', 'tests/linkTypes.test.ts'],
|
|
30
|
+
extends: commonConfig,
|
|
31
|
+
}),
|
|
32
|
+
withTestPreset({
|
|
33
|
+
name: 'plugin-i18n-client',
|
|
34
|
+
testEnvironment: 'happy-dom',
|
|
35
|
+
include: ['tests/routerAdapter.test.tsx', 'tests/link.test.tsx'],
|
|
36
|
+
extends: commonConfig,
|
|
37
|
+
}),
|
|
38
|
+
],
|
|
39
|
+
};
|
package/src/cli/index.ts
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import type { AppTools, CliPlugin } from '@modern-js/app-tools';
|
|
2
2
|
import { getPublicDirRoutePrefixes } from '@modern-js/server-core';
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
Entrypoint,
|
|
5
|
+
NestedRouteForCli,
|
|
6
|
+
PageRoute,
|
|
7
|
+
} from '@modern-js/types';
|
|
4
8
|
import fs from 'fs';
|
|
5
9
|
import path from 'path';
|
|
10
|
+
import {
|
|
11
|
+
applyLocalisedUrlsToRoutes,
|
|
12
|
+
resolveLocalisedUrlsConfig,
|
|
13
|
+
} from '../shared/localisedUrls';
|
|
6
14
|
import type { BackendOptions, LocaleDetectionOptions } from '../shared/type';
|
|
7
15
|
import { getBackendOptions, getLocaleDetectionOptions } from '../shared/utils';
|
|
16
|
+
import '../runtime/types';
|
|
8
17
|
|
|
9
18
|
export type TransformRuntimeConfigFn = (
|
|
10
19
|
extendedConfig: Record<string, any>,
|
|
@@ -203,6 +212,40 @@ export const i18nPlugin = (
|
|
|
203
212
|
};
|
|
204
213
|
});
|
|
205
214
|
|
|
215
|
+
api.modifyFileSystemRoutes(({ entrypoint, routes }) => {
|
|
216
|
+
if (!localeDetection) {
|
|
217
|
+
return { entrypoint, routes };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const localeDetectionOptions = getLocaleDetectionOptions(
|
|
221
|
+
entrypoint.entryName,
|
|
222
|
+
localeDetection,
|
|
223
|
+
);
|
|
224
|
+
const {
|
|
225
|
+
localePathRedirect,
|
|
226
|
+
languages = [],
|
|
227
|
+
localisedUrls,
|
|
228
|
+
} = localeDetectionOptions;
|
|
229
|
+
|
|
230
|
+
if (!localePathRedirect || languages.length === 0) {
|
|
231
|
+
return { entrypoint, routes };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const localisedUrlsConfig = resolveLocalisedUrlsConfig(localisedUrls);
|
|
235
|
+
if (!localisedUrlsConfig.enabled) {
|
|
236
|
+
return { entrypoint, routes };
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
entrypoint,
|
|
241
|
+
routes: applyLocalisedUrlsToRoutes(
|
|
242
|
+
routes as (NestedRouteForCli | PageRoute)[],
|
|
243
|
+
languages,
|
|
244
|
+
localisedUrlsConfig.map,
|
|
245
|
+
),
|
|
246
|
+
};
|
|
247
|
+
});
|
|
248
|
+
|
|
206
249
|
api._internalServerPlugins(({ plugins }) => {
|
|
207
250
|
const { serverRoutes, metaName } = api.getAppContext();
|
|
208
251
|
const normalizedConfig = api.getNormalizedConfig();
|
package/src/runtime/I18nLink.tsx
CHANGED
|
@@ -1,73 +1,36 @@
|
|
|
1
|
-
import { Link, useInRouterContext, useParams } from '@modern-js/runtime/router';
|
|
2
1
|
import type React from 'react';
|
|
3
|
-
import {
|
|
4
|
-
import { buildLocalizedUrl } from './utils';
|
|
2
|
+
import { Link } from './Link';
|
|
5
3
|
|
|
6
4
|
export interface I18nLinkProps {
|
|
7
5
|
to: string;
|
|
8
6
|
children: React.ReactNode;
|
|
9
|
-
[key: string]: any;
|
|
7
|
+
[key: string]: any;
|
|
10
8
|
}
|
|
11
9
|
|
|
10
|
+
let warnedDeprecation = false;
|
|
11
|
+
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* ```tsx
|
|
18
|
-
* // When current language is 'en' and to="/about"
|
|
19
|
-
* // The actual link will be "/en/about"
|
|
20
|
-
* <I18nLink to="/about">About</I18nLink>
|
|
21
|
-
*
|
|
22
|
-
* // When current language is 'zh' and to="/"
|
|
23
|
-
* // The actual link will be "/zh"
|
|
24
|
-
* <I18nLink to="/">Home</I18nLink>
|
|
25
|
-
* ```
|
|
13
|
+
* @deprecated Use {@link Link} from `@modern-js/plugin-i18n/runtime` instead.
|
|
14
|
+
* `Link` accepts the same language-agnostic `to` values and additionally
|
|
15
|
+
* supports `#hash`/`?query` targets, typed canonical routes, `params`
|
|
16
|
+
* interpolation and language-invariant active state.
|
|
26
17
|
*/
|
|
27
|
-
// Use static imports to avoid breaking router tree-shaking. Detect router context via useInRouterContext.
|
|
28
|
-
const useRouterHooks = () => {
|
|
29
|
-
const inRouter = useInRouterContext();
|
|
30
|
-
return {
|
|
31
|
-
Link: inRouter ? Link : null,
|
|
32
|
-
params: inRouter ? useParams() : ({} as any),
|
|
33
|
-
hasRouter: inRouter,
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
|
|
37
18
|
export const I18nLink: React.FC<I18nLinkProps> = ({
|
|
38
19
|
to,
|
|
39
20
|
children,
|
|
40
21
|
...props
|
|
41
22
|
}) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
// Get the current language from context (which reflects the actual current language)
|
|
46
|
-
// URL params might be stale after language changes, so we prioritize the context language
|
|
47
|
-
const currentLang = language;
|
|
48
|
-
|
|
49
|
-
// Build the localized URL by adding language prefix
|
|
50
|
-
const localizedTo = buildLocalizedUrl(to, currentLang, supportedLanguages);
|
|
51
|
-
|
|
52
|
-
// In development mode, warn if used outside of :lang route context
|
|
53
|
-
if (process.env.NODE_ENV === 'development' && hasRouter && !params.lang) {
|
|
23
|
+
if (process.env.NODE_ENV === 'development' && !warnedDeprecation) {
|
|
24
|
+
warnedDeprecation = true;
|
|
54
25
|
console.warn(
|
|
55
|
-
'I18nLink is
|
|
56
|
-
'
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// If router is not available, render as a regular anchor tag
|
|
61
|
-
if (!hasRouter || !Link) {
|
|
62
|
-
return (
|
|
63
|
-
<a href={localizedTo} {...props}>
|
|
64
|
-
{children}
|
|
65
|
-
</a>
|
|
26
|
+
'[plugin-i18n] I18nLink is deprecated. Import { Link } from ' +
|
|
27
|
+
"'@modern-js/plugin-i18n/runtime' instead — it accepts the same " +
|
|
28
|
+
'language-agnostic `to` values.',
|
|
66
29
|
);
|
|
67
30
|
}
|
|
68
31
|
|
|
69
32
|
return (
|
|
70
|
-
<Link to={
|
|
33
|
+
<Link to={to} {...props}>
|
|
71
34
|
{children}
|
|
72
35
|
</Link>
|
|
73
36
|
);
|