@bleedingdev/modern-js-plugin-i18n 3.8.3-ultramodern.6 → 3.9.0-ultramodern.10
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/dist/cjs/cli/index.js +10 -21
- package/dist/cjs/cli/localisedRoutes.js +46 -0
- package/dist/cjs/runtime/Link.js +19 -32
- package/dist/cjs/runtime/context.js +26 -61
- package/dist/cjs/runtime/contextHelpers.js +5 -5
- package/dist/cjs/runtime/core.js +27 -14
- package/dist/cjs/runtime/hooks.js +7 -8
- package/dist/cjs/runtime/localizedPaths.js +11 -9
- package/dist/cjs/runtime/navigation.js +48 -0
- package/dist/cjs/runtime/providerComposition.js +37 -13
- package/dist/cjs/runtime/routerAdapter.js +35 -140
- package/dist/cjs/runtime/utils.js +21 -19
- package/dist/cjs/server/defaultUrlStrategy.js +48 -0
- package/dist/cjs/server/index.js +11 -7
- package/dist/cjs/server/mappedUrlStrategy.js +43 -0
- package/dist/cjs/server/redirectPolicy.js +33 -24
- package/dist/cjs/shared/mappedUrlStrategy.js +63 -0
- package/dist/cjs/shared/urlStrategy.js +48 -0
- package/dist/esm/cli/index.mjs +10 -21
- package/dist/esm/cli/localisedRoutes.mjs +8 -0
- package/dist/esm/runtime/Link.mjs +19 -32
- package/dist/esm/runtime/context.mjs +18 -62
- package/dist/esm/runtime/contextHelpers.mjs +5 -5
- package/dist/esm/runtime/core.mjs +13 -6
- package/dist/esm/runtime/hooks.mjs +7 -8
- package/dist/esm/runtime/localizedPaths.mjs +11 -9
- package/dist/esm/runtime/navigation.mjs +7 -0
- package/dist/esm/runtime/providerComposition.mjs +38 -14
- package/dist/esm/runtime/routerAdapter.mjs +30 -141
- package/dist/esm/runtime/utils.mjs +19 -17
- package/dist/esm/server/defaultUrlStrategy.mjs +7 -0
- package/dist/esm/server/index.mjs +11 -7
- package/dist/esm/server/mappedUrlStrategy.mjs +1 -0
- package/dist/esm/server/redirectPolicy.mjs +33 -24
- package/dist/esm/shared/mappedUrlStrategy.mjs +19 -0
- package/dist/esm/shared/urlStrategy.mjs +7 -0
- package/dist/esm-node/cli/index.mjs +10 -21
- package/dist/esm-node/cli/localisedRoutes.mjs +9 -0
- package/dist/esm-node/runtime/Link.mjs +19 -32
- package/dist/esm-node/runtime/context.mjs +18 -62
- package/dist/esm-node/runtime/contextHelpers.mjs +5 -5
- package/dist/esm-node/runtime/core.mjs +13 -6
- package/dist/esm-node/runtime/hooks.mjs +7 -8
- package/dist/esm-node/runtime/localizedPaths.mjs +11 -9
- package/dist/esm-node/runtime/navigation.mjs +8 -0
- package/dist/esm-node/runtime/providerComposition.mjs +38 -14
- package/dist/esm-node/runtime/routerAdapter.mjs +30 -141
- package/dist/esm-node/runtime/utils.mjs +19 -17
- package/dist/esm-node/server/defaultUrlStrategy.mjs +8 -0
- package/dist/esm-node/server/index.mjs +11 -7
- package/dist/esm-node/server/mappedUrlStrategy.mjs +2 -0
- package/dist/esm-node/server/redirectPolicy.mjs +33 -24
- package/dist/esm-node/shared/mappedUrlStrategy.mjs +20 -0
- package/dist/esm-node/shared/urlStrategy.mjs +8 -0
- package/dist/types/cli/index.d.ts +2 -2
- package/dist/types/cli/locales.d.ts +1 -1
- package/dist/types/cli/localisedRoutes.d.ts +18 -0
- package/dist/types/runtime/Link.d.ts +2 -2
- package/dist/types/runtime/context.d.ts +10 -13
- package/dist/types/runtime/contextHelpers.d.ts +3 -3
- package/dist/types/runtime/core.d.ts +23 -13
- package/dist/types/runtime/hooks.d.ts +5 -6
- package/dist/types/runtime/i18n/backend/config.d.ts +1 -1
- package/dist/types/runtime/i18n/backend/index.d.ts +2 -2
- package/dist/types/runtime/i18n/backend/middleware.common.d.ts +2 -2
- package/dist/types/runtime/i18n/backend/middleware.d.ts +2 -2
- package/dist/types/runtime/i18n/backend/middleware.node.d.ts +2 -2
- package/dist/types/runtime/i18n/backend/sdk-backend.d.ts +1 -1
- package/dist/types/runtime/i18n/detection/cache.d.ts +1 -1
- package/dist/types/runtime/i18n/detection/config.d.ts +1 -1
- package/dist/types/runtime/i18n/detection/detector.d.ts +2 -2
- package/dist/types/runtime/i18n/detection/index.d.ts +4 -4
- package/dist/types/runtime/i18n/detection/initOptions.d.ts +1 -1
- package/dist/types/runtime/i18n/detection/middleware.d.ts +1 -1
- package/dist/types/runtime/i18n/detection/middleware.node.d.ts +1 -1
- package/dist/types/runtime/i18n/detection/priority.d.ts +2 -2
- package/dist/types/runtime/i18n/detection/types.d.ts +1 -1
- package/dist/types/runtime/i18n/index.d.ts +3 -3
- package/dist/types/runtime/i18n/instance.d.ts +1 -1
- package/dist/types/runtime/i18n/react-i18next.d.ts +1 -1
- package/dist/types/runtime/i18n/utils.d.ts +2 -2
- package/dist/types/runtime/index.d.ts +2 -2
- package/dist/types/runtime/localizedPaths.d.ts +4 -4
- package/dist/types/runtime/navigation.d.ts +10 -0
- package/dist/types/runtime/no-react-i18next.d.ts +2 -2
- package/dist/types/runtime/pluginSetup.d.ts +3 -3
- package/dist/types/runtime/providerComposition.d.ts +15 -3
- package/dist/types/runtime/routerAdapter.d.ts +23 -6
- package/dist/types/runtime/types.d.ts +1 -1
- package/dist/types/runtime/utils.d.ts +4 -12
- package/dist/types/server/defaultUrlStrategy.d.ts +11 -0
- package/dist/types/server/detectorOptions.d.ts +1 -1
- package/dist/types/server/index.d.ts +3 -1
- package/dist/types/server/mappedUrlStrategy.d.ts +7 -0
- package/dist/types/server/redirectPolicy.d.ts +5 -13
- package/dist/types/shared/mappedUrlStrategy.d.ts +27 -0
- package/dist/types/shared/type.d.ts +8 -12
- package/dist/types/shared/urlStrategy.d.ts +18 -0
- package/dist/types/shared/utils.d.ts +1 -1
- package/package.json +30 -18
- package/rstest.config.mts +6 -5
- package/src/cli/index.ts +42 -43
- package/src/cli/localisedRoutes.ts +43 -0
- package/src/runtime/Link.tsx +20 -40
- package/src/runtime/context.tsx +34 -133
- package/src/runtime/contextHelpers.ts +7 -5
- package/src/runtime/core.tsx +53 -6
- package/src/runtime/hooks.ts +14 -9
- package/src/runtime/i18n/instance.ts +1 -2
- package/src/runtime/localizedPaths.ts +24 -19
- package/src/runtime/navigation.tsx +20 -0
- package/src/runtime/providerComposition.tsx +71 -23
- package/src/runtime/routerAdapter.tsx +73 -338
- package/src/runtime/utils.ts +49 -31
- package/src/server/defaultUrlStrategy.ts +27 -0
- package/src/server/index.ts +39 -9
- package/src/server/mappedUrlStrategy.ts +10 -0
- package/src/server/redirectPolicy.ts +85 -70
- package/src/shared/mappedUrlStrategy.ts +59 -0
- package/src/shared/type.ts +7 -11
- package/src/shared/urlStrategy.ts +38 -0
- package/tests/backendDefaults.test.ts +2 -23
- package/tests/defaultUrlStrategy.test.ts +107 -0
- package/tests/federatedI18nBoundaryResolver.test.tsx +65 -0
- package/tests/i18nUtils.test.ts +31 -65
- package/tests/link.test.tsx +13 -511
- package/tests/localisedRouteGeneration.test.ts +159 -0
- package/tests/localisedUrls.test.ts +16 -208
- package/tests/mappedUrlStrategyDerivation.test.ts +62 -0
- package/tests/navigation.test.tsx +365 -0
- package/tests/reactI18nextRuntimeBoundary.test.ts +1 -82
- package/tests/redirectPolicy.test.ts +89 -27
- package/tests/routerAdapter.test.tsx +98 -1171
- package/tests/urlStrategySerialization.test.ts +122 -0
- package/tests/federatedI18nBoundary.client.test.tsx +0 -129
- package/tests/federatedI18nBoundary.test.tsx +0 -132
- package/tests/linkTypes.test.ts +0 -59
- package/tests/localisedUrlRewriteMatrix.fork.test.ts +0 -147
- package/tests/peerCohort.test.ts +0 -25
- package/tests/type-fixture/fixture-globals.d.ts +0 -11
- package/tests/type-fixture/i18nInstanceTypes.fixture.ts +0 -29
- package/tests/type-fixture/linkTypes.fixture.tsx +0 -51
- package/tests/type-fixture/tsconfig.json +0 -16
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
5
|
+
var define = (defs, kind)=>{
|
|
6
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
[kind]: defs[key]
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
define(getters, "get");
|
|
12
|
+
define(values, "value");
|
|
13
|
+
};
|
|
14
|
+
})();
|
|
15
|
+
(()=>{
|
|
16
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
17
|
+
})();
|
|
18
|
+
(()=>{
|
|
19
|
+
__webpack_require__.r = (exports1)=>{
|
|
20
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
21
|
+
value: 'Module'
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
24
|
+
value: true
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
})();
|
|
28
|
+
var __webpack_exports__ = {};
|
|
29
|
+
__webpack_require__.r(__webpack_exports__);
|
|
30
|
+
const asI18nUrlStrategy = (candidate)=>{
|
|
31
|
+
if (!candidate || 'object' != typeof candidate) return;
|
|
32
|
+
const strategy = candidate;
|
|
33
|
+
return 'function' == typeof strategy.localizePathname && 'function' == typeof strategy.canonicalPathname ? strategy : void 0;
|
|
34
|
+
};
|
|
35
|
+
const isUnusableI18nUrlStrategy = (candidate)=>Boolean(candidate) && 'object' == typeof candidate && void 0 === asI18nUrlStrategy(candidate);
|
|
36
|
+
__webpack_require__.d(__webpack_exports__, {}, {
|
|
37
|
+
asI18nUrlStrategy: asI18nUrlStrategy,
|
|
38
|
+
isUnusableI18nUrlStrategy: isUnusableI18nUrlStrategy
|
|
39
|
+
});
|
|
40
|
+
exports.asI18nUrlStrategy = __webpack_exports__.asI18nUrlStrategy;
|
|
41
|
+
exports.isUnusableI18nUrlStrategy = __webpack_exports__.isUnusableI18nUrlStrategy;
|
|
42
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
43
|
+
"asI18nUrlStrategy",
|
|
44
|
+
"isUnusableI18nUrlStrategy"
|
|
45
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
46
|
+
Object.defineProperty(exports, '__esModule', {
|
|
47
|
+
value: true
|
|
48
|
+
});
|
package/dist/esm/cli/index.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { applyLocalisedUrlsToRoutes, resolveLocalisedUrlsConfig } from "@modern-js/i18n-runtime-extensions";
|
|
2
1
|
import { getPublicDirRoutePrefixes } from "@modern-js/server-core";
|
|
2
|
+
import { logger } from "@modern-js/utils";
|
|
3
|
+
import { isUnusableI18nUrlStrategy } from "../shared/urlStrategy.mjs";
|
|
3
4
|
import { getBackendOptions, getLocaleDetectionOptions } from "../shared/utils.mjs";
|
|
4
5
|
import { applyDetectedBackendPaths, detectLocalesDirectory } from "./locales.mjs";
|
|
6
|
+
import { applyLocalisedRoutes } from "./localisedRoutes.mjs";
|
|
5
7
|
import "../runtime/types.mjs";
|
|
6
8
|
const i18nPlugin = (options = {})=>({
|
|
7
9
|
name: '@modern-js/plugin-i18n',
|
|
@@ -31,6 +33,10 @@ const i18nPlugin = (options = {})=>({
|
|
|
31
33
|
backend: backendOptions,
|
|
32
34
|
...extendedConfig
|
|
33
35
|
};
|
|
36
|
+
if (isUnusableI18nUrlStrategy(config.urlStrategy)) {
|
|
37
|
+
delete config.urlStrategy;
|
|
38
|
+
logger.warn("[i18n] `urlStrategy` cannot be passed through `modern.config.ts`: the generated runtime registration carries plugin options as JSON, which drops its methods. Configure `localeDetection.localisedUrls` instead — the runtime and the server both derive the URL policy from it — or register a runtime plugin that supplies the strategy directly.");
|
|
39
|
+
}
|
|
34
40
|
const { reactI18next } = extendedConfig;
|
|
35
41
|
const runtimePluginPath = customPlugin?.runtime?.path || (false === reactI18next ? `@${metaName}/plugin-i18n/runtime/no-react-i18next` : `@${metaName}/plugin-i18n/runtime`);
|
|
36
42
|
plugins.push({
|
|
@@ -43,27 +49,10 @@ const i18nPlugin = (options = {})=>({
|
|
|
43
49
|
plugins
|
|
44
50
|
};
|
|
45
51
|
});
|
|
46
|
-
api.modifyFileSystemRoutes(({ entrypoint, routes })=>{
|
|
47
|
-
if (!localeDetection) return {
|
|
52
|
+
api.modifyFileSystemRoutes(({ entrypoint, routes })=>({
|
|
48
53
|
entrypoint,
|
|
49
|
-
routes
|
|
50
|
-
};
|
|
51
|
-
const localeDetectionOptions = getLocaleDetectionOptions(entrypoint.entryName, localeDetection);
|
|
52
|
-
const { localePathRedirect, languages = [], localisedUrls } = localeDetectionOptions;
|
|
53
|
-
if (!localePathRedirect || 0 === languages.length) return {
|
|
54
|
-
entrypoint,
|
|
55
|
-
routes
|
|
56
|
-
};
|
|
57
|
-
const localisedUrlsConfig = resolveLocalisedUrlsConfig(localisedUrls);
|
|
58
|
-
if (!localisedUrlsConfig.enabled) return {
|
|
59
|
-
entrypoint,
|
|
60
|
-
routes
|
|
61
|
-
};
|
|
62
|
-
return {
|
|
63
|
-
entrypoint,
|
|
64
|
-
routes: applyLocalisedUrlsToRoutes(routes, languages, localisedUrlsConfig.map)
|
|
65
|
-
};
|
|
66
|
-
});
|
|
54
|
+
routes: applyLocalisedRoutes(routes, localeDetection ? getLocaleDetectionOptions(entrypoint.entryName, localeDetection) : void 0)
|
|
55
|
+
}));
|
|
67
56
|
api._internalServerPlugins(({ plugins })=>{
|
|
68
57
|
const { serverRoutes, metaName } = api.getAppContext();
|
|
69
58
|
const normalizedConfig = api.getNormalizedConfig();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { applyLocalisedUrlsToRoutes, resolveLocalisedUrlsConfig } from "@modern-js/i18n-runtime-extensions";
|
|
2
|
+
const applyLocalisedRoutes = (routes, localeDetection)=>{
|
|
3
|
+
const { localePathRedirect, languages = [], localisedUrls } = localeDetection ?? {};
|
|
4
|
+
const resolved = resolveLocalisedUrlsConfig(localisedUrls);
|
|
5
|
+
if (!localePathRedirect || !languages.length || !resolved.enabled) return routes;
|
|
6
|
+
return applyLocalisedUrlsToRoutes(routes, languages, resolved.map);
|
|
7
|
+
};
|
|
8
|
+
export { applyLocalisedRoutes };
|
|
@@ -9,10 +9,10 @@ const EXTERNAL_TARGET_RE = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
|
|
|
9
9
|
const Link = (props)=>{
|
|
10
10
|
const { to, params, children, hash: hashProp, search: searchProp, hashScrollIntoView, activeOptions, activeProps, prefetch, preload, ...rest } = props;
|
|
11
11
|
const adapter = useI18nRouterAdapter();
|
|
12
|
-
const { language, supportedLanguages,
|
|
12
|
+
const { language, supportedLanguages, urlStrategy } = useModernI18n();
|
|
13
13
|
const config = {
|
|
14
14
|
languages: supportedLanguages,
|
|
15
|
-
|
|
15
|
+
urlStrategy
|
|
16
16
|
};
|
|
17
17
|
const isExternal = EXTERNAL_TARGET_RE.test(to);
|
|
18
18
|
const isBareHash = to.startsWith('#');
|
|
@@ -22,7 +22,7 @@ const Link = (props)=>{
|
|
|
22
22
|
const interpolated = interpolateRouteParams(pathname || '/', params);
|
|
23
23
|
const firstSegment = interpolated.split('/').filter(Boolean)[0];
|
|
24
24
|
if (firstSegment && supportedLanguages.includes(firstSegment)) warnOnce(`lang-prefix:${to}`, `[plugin-i18n] <Link to="${to}"> starts with a language prefix. Write language-agnostic canonical paths; the Link localizes them automatically.`);
|
|
25
|
-
const localizedPathname = buildLocalizedUrl(interpolated, language, supportedLanguages,
|
|
25
|
+
const localizedPathname = buildLocalizedUrl(interpolated, language, supportedLanguages, urlStrategy);
|
|
26
26
|
const hash = hashProp ?? (hashFromTo ? hashFromTo.slice(1) : '');
|
|
27
27
|
const { searchString, searchObject } = normalizeSearch(searchProp, searchFromTo);
|
|
28
28
|
return {
|
|
@@ -42,7 +42,7 @@ const Link = (props)=>{
|
|
|
42
42
|
isBareHash,
|
|
43
43
|
language,
|
|
44
44
|
supportedLanguages,
|
|
45
|
-
|
|
45
|
+
urlStrategy
|
|
46
46
|
]);
|
|
47
47
|
const isActive = useMemo(()=>{
|
|
48
48
|
if (!target || !adapter.location) return false;
|
|
@@ -57,7 +57,7 @@ const Link = (props)=>{
|
|
|
57
57
|
adapter.location,
|
|
58
58
|
activeOptions?.exact,
|
|
59
59
|
supportedLanguages,
|
|
60
|
-
|
|
60
|
+
urlStrategy
|
|
61
61
|
]);
|
|
62
62
|
const resolvedActiveProps = splitActiveProps(isActive, activeProps);
|
|
63
63
|
const activeAttributes = isActive ? {
|
|
@@ -72,7 +72,7 @@ const Link = (props)=>{
|
|
|
72
72
|
children: children
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
|
-
const { Link: RouterLink, hasRouter
|
|
75
|
+
const { Link: RouterLink, hasRouter } = adapter;
|
|
76
76
|
if (!hasRouter || !RouterLink) {
|
|
77
77
|
const { replace: _replace, ...anchorProps } = rest;
|
|
78
78
|
const { className: activeClassName, style: activeStyle, ...activeRest } = resolvedActiveProps;
|
|
@@ -95,38 +95,25 @@ const Link = (props)=>{
|
|
|
95
95
|
...rest.style,
|
|
96
96
|
...activeStyle
|
|
97
97
|
};
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
} : {},
|
|
108
|
-
...void 0 === hashScrollIntoView ? {} : {
|
|
109
|
-
hashScrollIntoView
|
|
110
|
-
},
|
|
111
|
-
...void 0 === tanstackPreload ? {} : {
|
|
112
|
-
preload: tanstackPreload
|
|
113
|
-
},
|
|
114
|
-
...rest,
|
|
115
|
-
...activeRest,
|
|
116
|
-
...activeAttributes,
|
|
117
|
-
className: mergedClassName,
|
|
118
|
-
style: mergedStyle,
|
|
119
|
-
children: children
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
return /*#__PURE__*/ jsx(RouterLink, {
|
|
98
|
+
const routerProps = adapter.createLinkProps?.({
|
|
99
|
+
pathname: target.localizedPathname,
|
|
100
|
+
href: target.href,
|
|
101
|
+
search: target.searchObject,
|
|
102
|
+
hash: target.hash,
|
|
103
|
+
hashScrollIntoView,
|
|
104
|
+
prefetch,
|
|
105
|
+
preload
|
|
106
|
+
}) ?? {
|
|
123
107
|
to: target.href,
|
|
124
108
|
...void 0 === prefetch ? {} : {
|
|
125
109
|
prefetch
|
|
126
110
|
},
|
|
127
111
|
...void 0 === preload ? {} : {
|
|
128
112
|
preload
|
|
129
|
-
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
return /*#__PURE__*/ jsx(RouterLink, {
|
|
116
|
+
...routerProps,
|
|
130
117
|
...rest,
|
|
131
118
|
...activeRest,
|
|
132
119
|
...activeAttributes,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { RuntimeComponentResolverContext } from "@modern-js/runtime/context";
|
|
2
3
|
import { createContext, useCallback, useContext, useEffect, useMemo } from "react";
|
|
3
4
|
import { changeModernI18nLanguage, getPathLanguage, isI18nLanguageSupported, isI18nResourcesReady, translateI18n } from "./contextHelpers.mjs";
|
|
4
|
-
import { getActualI18nextInstance } from "./i18n/instance.mjs";
|
|
5
5
|
import { useI18nRouterAdapter } from "./routerAdapter.mjs";
|
|
6
6
|
const modernI18nContextKey = Symbol.for('@modern-js/plugin-i18n/runtime/ModernI18nContext');
|
|
7
7
|
const reactI18nextProviderContextKey = Symbol.for('@modern-js/plugin-i18n/runtime/ReactI18nextProviderContext');
|
|
@@ -22,68 +22,23 @@ const ModernI18nProvider = ({ children, i18nextProvider, value })=>{
|
|
|
22
22
|
children: content
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
initImmediate: false,
|
|
37
|
-
lng: parent.language,
|
|
38
|
-
ns: [
|
|
39
|
-
defaultNamespace
|
|
40
|
-
],
|
|
41
|
-
resources,
|
|
42
|
-
supportedLngs: languages
|
|
43
|
-
});
|
|
44
|
-
if (!clone) throw new Error('FederatedI18nBoundary requires an i18n instance with cloneInstance support');
|
|
45
|
-
const resourceStore = clone.store;
|
|
46
|
-
const parentResourceStore = parentInstance.store;
|
|
47
|
-
const sharesNestedResourceState = Object.entries(resourceStore?.data ?? {}).some(([language, namespaces])=>{
|
|
48
|
-
const parentNamespaces = parentResourceStore?.data?.[language];
|
|
49
|
-
return namespaces === parentNamespaces || Object.entries(namespaces).some(([namespace, resource])=>null !== resource && 'object' == typeof resource && resource === parentNamespaces?.[namespace]);
|
|
50
|
-
});
|
|
51
|
-
if (clone === parentInstance || resourceStore === parentResourceStore || resourceStore?.data === parentResourceStore?.data || sharesNestedResourceState) throw new Error('FederatedI18nBoundary cloneInstance did not isolate the host resource store');
|
|
52
|
-
if (!resourceStore?.addResourceBundle || !clone.removeResourceBundle || !resourceStore.data) throw new Error('FederatedI18nBoundary requires an isolated mutable i18n resource store');
|
|
53
|
-
for (const [language, namespaces] of Object.entries(resourceStore.data))for (const namespace of Object.keys(namespaces))clone.removeResourceBundle(language, namespace);
|
|
54
|
-
for (const [language, namespaces] of Object.entries(resources))for (const [namespace, resource] of Object.entries(namespaces))resourceStore.addResourceBundle(language, namespace, resource, true, true);
|
|
55
|
-
return clone;
|
|
56
|
-
}, [
|
|
57
|
-
defaultNamespace,
|
|
58
|
-
fallbackLanguage,
|
|
59
|
-
languages,
|
|
60
|
-
parent.i18nInstance,
|
|
61
|
-
parent.language,
|
|
62
|
-
resources
|
|
63
|
-
]);
|
|
64
|
-
const value = useMemo(()=>({
|
|
65
|
-
...parent,
|
|
66
|
-
i18nInstance: scopedInstance,
|
|
67
|
-
language: parent.language,
|
|
68
|
-
languages
|
|
69
|
-
}), [
|
|
70
|
-
languages,
|
|
71
|
-
parent,
|
|
72
|
-
scopedInstance
|
|
73
|
-
]);
|
|
74
|
-
const scopedContent = /*#__PURE__*/ jsx(ModernI18nProvider, {
|
|
75
|
-
value: value,
|
|
76
|
-
children: children
|
|
25
|
+
const MissingFederatedI18nBoundary = ()=>{
|
|
26
|
+
throw new Error('FederatedI18nBoundary requires the @modern-js/i18n-integration runtime plugin');
|
|
27
|
+
};
|
|
28
|
+
const FederatedI18nBoundary = (props)=>{
|
|
29
|
+
const resolveComponent = useContext(RuntimeComponentResolverContext);
|
|
30
|
+
const Boundary = resolveComponent?.(MissingFederatedI18nBoundary, {
|
|
31
|
+
name: 'i18n.FederatedI18nBoundary'
|
|
32
|
+
}) ?? MissingFederatedI18nBoundary;
|
|
33
|
+
if (Boundary === FederatedI18nBoundary) throw new Error('FederatedI18nBoundary resolver returned its own wrapper');
|
|
34
|
+
return /*#__PURE__*/ jsx(Boundary, {
|
|
35
|
+
...props
|
|
77
36
|
});
|
|
78
|
-
return I18nextProvider ? /*#__PURE__*/ jsx(I18nextProvider, {
|
|
79
|
-
i18n: scopedInstance,
|
|
80
|
-
children: scopedContent
|
|
81
|
-
}) : scopedContent;
|
|
82
37
|
};
|
|
83
38
|
const useModernI18n = ()=>{
|
|
84
39
|
const context = useContext(ModernI18nContext);
|
|
85
40
|
if (!context) throw new Error('useModernI18n must be used within ModernI18nProvider');
|
|
86
|
-
const { language: contextLanguage, i18nInstance, languages, localePathRedirect, ignoreRedirectRoutes,
|
|
41
|
+
const { language: contextLanguage, i18nInstance, languages, localePathRedirect, ignoreRedirectRoutes, urlStrategy, updateLanguage, synchronizeLanguage } = context;
|
|
87
42
|
const { navigate, location, hasRouter } = useI18nRouterAdapter();
|
|
88
43
|
const pathLanguage = useMemo(()=>getPathLanguage(location?.pathname, languages, localePathRedirect), [
|
|
89
44
|
languages,
|
|
@@ -102,7 +57,7 @@ const useModernI18n = ()=>{
|
|
|
102
57
|
updateLanguage,
|
|
103
58
|
localePathRedirect,
|
|
104
59
|
ignoreRedirectRoutes,
|
|
105
|
-
|
|
60
|
+
urlStrategy,
|
|
106
61
|
languages,
|
|
107
62
|
hasRouter,
|
|
108
63
|
navigate,
|
|
@@ -112,7 +67,7 @@ const useModernI18n = ()=>{
|
|
|
112
67
|
updateLanguage,
|
|
113
68
|
localePathRedirect,
|
|
114
69
|
ignoreRedirectRoutes,
|
|
115
|
-
|
|
70
|
+
urlStrategy,
|
|
116
71
|
languages,
|
|
117
72
|
hasRouter,
|
|
118
73
|
navigate,
|
|
@@ -135,9 +90,10 @@ const useModernI18n = ()=>{
|
|
|
135
90
|
t,
|
|
136
91
|
i18nInstance: i18nInstance,
|
|
137
92
|
supportedLanguages: languages || [],
|
|
138
|
-
|
|
93
|
+
urlStrategy,
|
|
139
94
|
isLanguageSupported,
|
|
140
95
|
isResourcesReady
|
|
141
96
|
};
|
|
142
97
|
};
|
|
143
|
-
export {
|
|
98
|
+
export { getActualI18nextInstance } from "./i18n/instance.mjs";
|
|
99
|
+
export { FederatedI18nBoundary, ModernI18nContext, ModernI18nProvider, ReactI18nextProviderContext, useModernI18n };
|
|
@@ -17,7 +17,7 @@ async function changeI18nInstanceLanguage(i18nInstance, language) {
|
|
|
17
17
|
else await i18nInstance.changeLanguage?.(language);
|
|
18
18
|
}
|
|
19
19
|
async function changeModernI18nLanguage(newLang, options) {
|
|
20
|
-
const { i18nInstance, updateLanguage, localePathRedirect, ignoreRedirectRoutes,
|
|
20
|
+
const { i18nInstance, updateLanguage, localePathRedirect, ignoreRedirectRoutes, urlStrategy, languages, hasRouter, navigate, location } = options;
|
|
21
21
|
try {
|
|
22
22
|
if (!newLang || 'string' != typeof newLang) throw new Error('Language must be non-empty string');
|
|
23
23
|
await changeI18nInstanceLanguage(i18nInstance, newLang);
|
|
@@ -28,8 +28,8 @@ async function changeModernI18nLanguage(newLang, options) {
|
|
|
28
28
|
const relativePath = currentPath.replace(entryPath, '');
|
|
29
29
|
const pathLanguage = detectLanguageFromPath(currentPath, languages || [], localePathRedirect);
|
|
30
30
|
if (pathLanguage.detected && pathLanguage.language === newLang) return void updateLanguage?.(newLang);
|
|
31
|
-
if (!shouldIgnoreRedirect(relativePath, languages || [], ignoreRedirectRoutes)) {
|
|
32
|
-
const newPath = buildLocalizedUrl(relativePath, newLang, languages || [],
|
|
31
|
+
if (!shouldIgnoreRedirect(relativePath, languages || [], ignoreRedirectRoutes, urlStrategy)) {
|
|
32
|
+
const newPath = buildLocalizedUrl(relativePath, newLang, languages || [], urlStrategy);
|
|
33
33
|
const newUrl = entryPath + newPath + location.search + location.hash;
|
|
34
34
|
await navigate(newUrl, {
|
|
35
35
|
replace: true
|
|
@@ -41,8 +41,8 @@ async function changeModernI18nLanguage(newLang, options) {
|
|
|
41
41
|
const relativePath = currentPath.replace(entryPath, '');
|
|
42
42
|
const pathLanguage = detectLanguageFromPath(currentPath, languages || [], localePathRedirect);
|
|
43
43
|
if (pathLanguage.detected && pathLanguage.language === newLang) return void updateLanguage?.(newLang);
|
|
44
|
-
if (!shouldIgnoreRedirect(relativePath, languages || [], ignoreRedirectRoutes)) {
|
|
45
|
-
const newPath = buildLocalizedUrl(relativePath, newLang, languages || [],
|
|
44
|
+
if (!shouldIgnoreRedirect(relativePath, languages || [], ignoreRedirectRoutes, urlStrategy)) {
|
|
45
|
+
const newPath = buildLocalizedUrl(relativePath, newLang, languages || [], urlStrategy);
|
|
46
46
|
const newUrl = entryPath + newPath + window.location.search + window.location.hash;
|
|
47
47
|
window.history.pushState(null, '', newUrl);
|
|
48
48
|
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { resolveMappedUrlStrategy } from "../shared/mappedUrlStrategy.mjs";
|
|
2
|
+
import { asI18nUrlStrategy } from "../shared/urlStrategy.mjs";
|
|
3
|
+
import { I18nRouterNavigationProvider, useIntegratedRouterAdapter } from "./navigation.mjs";
|
|
1
4
|
import { setupI18nBeforeRender } from "./pluginSetup.mjs";
|
|
2
5
|
import { createI18nRootWrapper } from "./providerComposition.mjs";
|
|
3
6
|
import { resolveReactI18nextIntegration } from "./reactI18next.mjs";
|
|
@@ -5,9 +8,10 @@ import "./types.mjs";
|
|
|
5
8
|
const createI18nPlugin = (loadReactI18nextIntegration)=>(options)=>({
|
|
6
9
|
name: '@modern-js/plugin-i18n',
|
|
7
10
|
setup: (api)=>{
|
|
8
|
-
const { entryName, i18nInstance: userI18nInstance, initOptions, localeDetection, backend, htmlLangAttr = false, reactI18next = true } = options;
|
|
9
|
-
const { localePathRedirect = false, i18nextDetector = true, languages = [], fallbackLanguage = 'en', detection, ignoreRedirectRoutes
|
|
11
|
+
const { entryName, i18nInstance: userI18nInstance, initOptions, localeDetection, backend, htmlLangAttr = false, reactI18next = true, urlStrategy, NavigationProvider, LanguageSynchronization } = options;
|
|
12
|
+
const { localePathRedirect = false, i18nextDetector = true, languages = [], fallbackLanguage = 'en', detection, ignoreRedirectRoutes } = localeDetection || {};
|
|
10
13
|
const { enabled: backendEnabled = false } = backend || {};
|
|
14
|
+
const resolvedUrlStrategy = asI18nUrlStrategy(urlStrategy) ?? resolveMappedUrlStrategy(localeDetection);
|
|
11
15
|
let latestI18nInstance;
|
|
12
16
|
let I18nextProvider;
|
|
13
17
|
api.onBeforeRender(async (context)=>{
|
|
@@ -35,15 +39,18 @@ const createI18nPlugin = (loadReactI18nextIntegration)=>(options)=>({
|
|
|
35
39
|
languages,
|
|
36
40
|
fallbackLanguage,
|
|
37
41
|
ignoreRedirectRoutes,
|
|
38
|
-
|
|
42
|
+
urlStrategy: resolvedUrlStrategy,
|
|
43
|
+
NavigationProvider: NavigationProvider ?? I18nRouterNavigationProvider,
|
|
44
|
+
LanguageSynchronization,
|
|
39
45
|
getLatestI18nInstance: ()=>latestI18nInstance,
|
|
40
46
|
getI18nextProvider: ()=>I18nextProvider
|
|
41
47
|
}));
|
|
42
48
|
}
|
|
43
49
|
});
|
|
50
|
+
export { I18nNavigationProvider, useI18nRouterAdapter, useNativeI18nRouterAdapter } from "./routerAdapter.mjs";
|
|
44
51
|
export { FederatedI18nBoundary, useModernI18n } from "./context.mjs";
|
|
45
52
|
export { I18nLink } from "./I18nLink.mjs";
|
|
46
53
|
export { Link } from "./Link.mjs";
|
|
47
|
-
export {
|
|
48
|
-
export {
|
|
49
|
-
export { createI18nPlugin };
|
|
54
|
+
export { useLocalizedLocation, useLocalizedPaths } from "./localizedPaths.mjs";
|
|
55
|
+
export { splitUrlTarget } from "./utils.mjs";
|
|
56
|
+
export { I18nRouterNavigationProvider, createI18nPlugin, useIntegratedRouterAdapter };
|
|
@@ -18,7 +18,7 @@ function createMinimalI18nInstance(language) {
|
|
|
18
18
|
};
|
|
19
19
|
return minimalInstance;
|
|
20
20
|
}
|
|
21
|
-
function createContextValue(lang, i18nInstance, entryName, languages, localePathRedirect, ignoreRedirectRoutes,
|
|
21
|
+
function createContextValue(lang, i18nInstance, entryName, languages, localePathRedirect, ignoreRedirectRoutes, setLang, urlStrategy) {
|
|
22
22
|
const instance = i18nInstance || createMinimalI18nInstance(lang);
|
|
23
23
|
return {
|
|
24
24
|
language: lang,
|
|
@@ -27,9 +27,8 @@ function createContextValue(lang, i18nInstance, entryName, languages, localePath
|
|
|
27
27
|
languages,
|
|
28
28
|
localePathRedirect,
|
|
29
29
|
ignoreRedirectRoutes,
|
|
30
|
-
|
|
31
|
-
updateLanguage: setLang
|
|
32
|
-
synchronizeLanguage
|
|
30
|
+
urlStrategy,
|
|
31
|
+
updateLanguage: setLang
|
|
33
32
|
};
|
|
34
33
|
}
|
|
35
34
|
function useSdkResourcesLoader(i18nInstance, setForceUpdate) {
|
|
@@ -78,7 +77,7 @@ function useSdkResourcesLoader(i18nInstance, setForceUpdate) {
|
|
|
78
77
|
setForceUpdate
|
|
79
78
|
]);
|
|
80
79
|
}
|
|
81
|
-
function useClientSideRedirect(i18nInstance, localePathRedirect, languages, fallbackLanguage, ignoreRedirectRoutes,
|
|
80
|
+
function useClientSideRedirect(i18nInstance, localePathRedirect, languages, fallbackLanguage, ignoreRedirectRoutes, urlStrategy) {
|
|
82
81
|
const urlRef = useRef('');
|
|
83
82
|
const { navigate, location, hasRouter } = useI18nRouterAdapter();
|
|
84
83
|
useEffect(()=>{
|
|
@@ -95,10 +94,10 @@ function useClientSideRedirect(i18nInstance, localePathRedirect, languages, fall
|
|
|
95
94
|
const currentHash = hasRouter && location ? location.hash : window.location.hash;
|
|
96
95
|
const entryPath = getEntryPath();
|
|
97
96
|
const relativePath = currentPathname.replace(entryPath, '');
|
|
98
|
-
if (shouldIgnoreRedirect(relativePath, languages, ignoreRedirectRoutes)) return;
|
|
97
|
+
if (shouldIgnoreRedirect(relativePath, languages, ignoreRedirectRoutes, urlStrategy)) return;
|
|
99
98
|
const pathDetection = detectLanguageFromPath(currentPathname, languages, localePathRedirect);
|
|
100
99
|
const targetLanguage = pathDetection.language || i18nInstance.language || fallbackLanguage || languages[0] || 'en';
|
|
101
|
-
const newPath = buildLocalizedUrl(relativePath, targetLanguage, languages,
|
|
100
|
+
const newPath = buildLocalizedUrl(relativePath, targetLanguage, languages, urlStrategy);
|
|
102
101
|
const newUrl = entryPath + newPath + currentSearch + currentHash;
|
|
103
102
|
urlRef.current = currentPathname;
|
|
104
103
|
if (newUrl !== currentPathname + currentSearch + currentHash) if (hasRouter && navigate && location) navigate(newUrl, {
|
|
@@ -114,7 +113,7 @@ function useClientSideRedirect(i18nInstance, localePathRedirect, languages, fall
|
|
|
114
113
|
languages,
|
|
115
114
|
fallbackLanguage,
|
|
116
115
|
ignoreRedirectRoutes,
|
|
117
|
-
|
|
116
|
+
urlStrategy
|
|
118
117
|
]);
|
|
119
118
|
}
|
|
120
119
|
function useLanguageSync(i18nInstance, localePathRedirect, languages, pathname, prevLangRef, setLang) {
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { canonicalTargetPathname } from "@modern-js/i18n-runtime-extensions";
|
|
2
1
|
import { useMemo } from "react";
|
|
3
2
|
import { useModernI18n } from "./context.mjs";
|
|
4
3
|
import { useI18nRouterAdapter } from "./routerAdapter.mjs";
|
|
5
4
|
import { buildLocalizedUrl, splitUrlTarget } from "./utils.mjs";
|
|
6
|
-
const localizePath = (pathname, language, config)=>buildLocalizedUrl(pathname, language, config.languages, config.
|
|
5
|
+
const localizePath = (pathname, language, config)=>buildLocalizedUrl(pathname, language, config.languages, config.urlStrategy);
|
|
7
6
|
const canonicalPath = (target, config)=>{
|
|
8
7
|
const { pathname, search, hash } = splitUrlTarget(target);
|
|
9
|
-
|
|
8
|
+
if (config.urlStrategy) return `${config.urlStrategy.canonicalPathname(pathname, config.languages)}${search}${hash}`;
|
|
9
|
+
const segments = pathname.split('/').filter(Boolean);
|
|
10
|
+
if (segments[0] && config.languages.some((language)=>language.toLowerCase() === segments[0].toLowerCase())) segments.shift();
|
|
11
|
+
const resolvedPath = `/${segments.join('/')}`;
|
|
10
12
|
return `${resolvedPath}${search}${hash}`;
|
|
11
13
|
};
|
|
12
14
|
const useLocalizedPaths = ()=>{
|
|
13
|
-
const { supportedLanguages,
|
|
15
|
+
const { supportedLanguages, urlStrategy } = useModernI18n();
|
|
14
16
|
return useMemo(()=>{
|
|
15
17
|
const config = {
|
|
16
18
|
languages: supportedLanguages,
|
|
17
|
-
|
|
19
|
+
urlStrategy
|
|
18
20
|
};
|
|
19
21
|
return {
|
|
20
22
|
localizePath: (pathname, language)=>localizePath(pathname, language, config),
|
|
@@ -22,11 +24,11 @@ const useLocalizedPaths = ()=>{
|
|
|
22
24
|
};
|
|
23
25
|
}, [
|
|
24
26
|
supportedLanguages,
|
|
25
|
-
|
|
27
|
+
urlStrategy
|
|
26
28
|
]);
|
|
27
29
|
};
|
|
28
30
|
const useLocalizedLocation = ()=>{
|
|
29
|
-
const { language, supportedLanguages,
|
|
31
|
+
const { language, supportedLanguages, urlStrategy } = useModernI18n();
|
|
30
32
|
const { location } = useI18nRouterAdapter();
|
|
31
33
|
const pathname = location?.pathname ?? '/';
|
|
32
34
|
const search = location?.search ?? '';
|
|
@@ -34,7 +36,7 @@ const useLocalizedLocation = ()=>{
|
|
|
34
36
|
return useMemo(()=>{
|
|
35
37
|
const config = {
|
|
36
38
|
languages: supportedLanguages,
|
|
37
|
-
|
|
39
|
+
urlStrategy
|
|
38
40
|
};
|
|
39
41
|
const alternates = {};
|
|
40
42
|
for (const supportedLanguage of supportedLanguages)alternates[supportedLanguage] = `${localizePath(pathname, supportedLanguage, config)}${search}${hash}`;
|
|
@@ -46,7 +48,7 @@ const useLocalizedLocation = ()=>{
|
|
|
46
48
|
}, [
|
|
47
49
|
language,
|
|
48
50
|
supportedLanguages,
|
|
49
|
-
|
|
51
|
+
urlStrategy,
|
|
50
52
|
pathname,
|
|
51
53
|
search,
|
|
52
54
|
hash
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createI18nRouterNavigation } from "@modern-js/i18n-runtime-extensions/router-navigation";
|
|
2
|
+
import { I18nNavigationProvider, useNativeI18nRouterAdapter } from "./routerAdapter.mjs";
|
|
3
|
+
const { I18nRouterNavigationProvider: I18nRouterNavigationProvider, useIntegratedRouterAdapter: useIntegratedRouterAdapter } = createI18nRouterNavigation({
|
|
4
|
+
I18nNavigationProvider: I18nNavigationProvider,
|
|
5
|
+
useNativeI18nRouterAdapter: useNativeI18nRouterAdapter
|
|
6
|
+
});
|
|
7
|
+
export { I18nRouterNavigationProvider, useIntegratedRouterAdapter };
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useLanguageSync } from "@modern-js/i18n-runtime-extensions";
|
|
3
2
|
import { RuntimeContext } from "@modern-js/runtime";
|
|
4
3
|
import { Helmet } from "@modern-js/runtime/head";
|
|
5
4
|
import { useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
6
5
|
import { ModernI18nProvider } from "./context.mjs";
|
|
7
|
-
import { createContextValue, useClientSideRedirect, useSdkResourcesLoader } from "./hooks.mjs";
|
|
6
|
+
import { createContextValue, useClientSideRedirect, useLanguageSync, useSdkResourcesLoader } from "./hooks.mjs";
|
|
8
7
|
import { getI18nextInstanceForProvider } from "./i18n/instance.mjs";
|
|
9
8
|
import { useI18nRouterAdapter } from "./routerAdapter.mjs";
|
|
10
|
-
const
|
|
11
|
-
|
|
9
|
+
const NativeLanguageSynchronization = ({ i18nInstance, localePathRedirect, languages, pathname, prevLangRef, setLang, children })=>{
|
|
10
|
+
const synchronizeLanguage = useLanguageSync(i18nInstance, localePathRedirect, languages, pathname, prevLangRef, setLang);
|
|
11
|
+
return children(synchronizeLanguage);
|
|
12
|
+
};
|
|
13
|
+
const createI18nRootWrapper = (options)=>(App)=>{
|
|
14
|
+
const LanguageSynchronization = options.LanguageSynchronization ?? NativeLanguageSynchronization;
|
|
15
|
+
const I18nRoot = (props)=>{
|
|
16
|
+
const { entryName, htmlLangAttr, localePathRedirect, languages, fallbackLanguage, ignoreRedirectRoutes, urlStrategy, getLatestI18nInstance, getI18nextProvider } = options;
|
|
12
17
|
const runtimeContext = useContext(RuntimeContext);
|
|
13
18
|
const i18nInstance = runtimeContext.i18nInstance || getLatestI18nInstance();
|
|
14
19
|
const initialLang = useMemo(()=>i18nInstance?.language || fallbackLanguage, [
|
|
@@ -33,18 +38,16 @@ const createI18nRootWrapper = (options)=>(App)=>(props)=>{
|
|
|
33
38
|
lang
|
|
34
39
|
]);
|
|
35
40
|
useSdkResourcesLoader(i18nInstance, setForceUpdate);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const contextValue = useMemo(()=>createContextValue(lang, i18nInstance, entryName, languages, localePathRedirect, ignoreRedirectRoutes, localisedUrls, setLang, synchronizeLanguage), [
|
|
41
|
+
useClientSideRedirect(i18nInstance, localePathRedirect, languages, fallbackLanguage, ignoreRedirectRoutes, urlStrategy);
|
|
42
|
+
const contextValue = useMemo(()=>createContextValue(lang, i18nInstance, entryName, languages, localePathRedirect, ignoreRedirectRoutes, setLang, urlStrategy), [
|
|
39
43
|
lang,
|
|
40
44
|
i18nInstance,
|
|
41
45
|
entryName,
|
|
42
46
|
languages,
|
|
43
47
|
localePathRedirect,
|
|
44
48
|
ignoreRedirectRoutes,
|
|
45
|
-
|
|
46
|
-
forceUpdate
|
|
47
|
-
synchronizeLanguage
|
|
49
|
+
urlStrategy,
|
|
50
|
+
forceUpdate
|
|
48
51
|
]);
|
|
49
52
|
const I18nextProvider = getI18nextProvider();
|
|
50
53
|
const i18nextInstanceForProvider = useMemo(()=>i18nInstance ? getI18nextInstanceForProvider(i18nInstance, lang) : void 0, [
|
|
@@ -67,12 +70,33 @@ const createI18nRootWrapper = (options)=>(App)=>(props)=>{
|
|
|
67
70
|
lang
|
|
68
71
|
}
|
|
69
72
|
}),
|
|
70
|
-
/*#__PURE__*/ jsx(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
/*#__PURE__*/ jsx(LanguageSynchronization, {
|
|
74
|
+
i18nInstance: i18nInstance,
|
|
75
|
+
localePathRedirect: localePathRedirect,
|
|
76
|
+
languages: languages,
|
|
77
|
+
pathname: location?.pathname,
|
|
78
|
+
prevLangRef: prevLangRef,
|
|
79
|
+
setLang: setLang,
|
|
80
|
+
children: (synchronizeLanguage)=>/*#__PURE__*/ jsx(ModernI18nProvider, {
|
|
81
|
+
i18nextProvider: I18nextProvider,
|
|
82
|
+
value: {
|
|
83
|
+
...contextValue,
|
|
84
|
+
synchronizeLanguage
|
|
85
|
+
},
|
|
86
|
+
children: appContent
|
|
87
|
+
})
|
|
74
88
|
})
|
|
75
89
|
]
|
|
76
90
|
});
|
|
77
91
|
};
|
|
92
|
+
const { NavigationProvider } = options;
|
|
93
|
+
if (!NavigationProvider) return I18nRoot;
|
|
94
|
+
return function(props) {
|
|
95
|
+
return /*#__PURE__*/ jsx(NavigationProvider, {
|
|
96
|
+
children: /*#__PURE__*/ jsx(I18nRoot, {
|
|
97
|
+
...props
|
|
98
|
+
})
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
};
|
|
78
102
|
export { createI18nRootWrapper };
|