@intlayer/next-i18next 9.2.0 → 9.3.1
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 +24 -24
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -2
- package/dist/cjs/appWithTranslation.cjs +2 -1
- package/dist/cjs/appWithTranslation.cjs.map +1 -1
- package/dist/cjs/plugin/index.cjs +4 -3
- package/dist/cjs/plugin/index.cjs.map +1 -1
- package/dist/cjs/serverSideTranslations.cjs.map +1 -1
- package/dist/esm/appWithTranslation.mjs +2 -1
- package/dist/esm/appWithTranslation.mjs.map +1 -1
- package/dist/esm/plugin/index.mjs +4 -3
- package/dist/esm/plugin/index.mjs.map +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -47,27 +47,27 @@ With **per-locale content files**, **TypeScript autocompletion**, **tree-shakabl
|
|
|
47
47
|
|
|
48
48
|
## Keys benefits of Intlayer:
|
|
49
49
|
|
|
50
|
-
| Feature | Description
|
|
51
|
-
| --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/frameworks.png?raw=true" alt="Feature" width="700"> | **Cross-Frameworks Support**<br><br>Intlayer is compatible with all major frameworks and libraries, including Next.js, React, Vite, Vue.js, Nuxt, Preact, Express, and more.
|
|
53
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/javascript_content_management.jpg?raw=true" alt="Feature" width="700"> | **JavaScript-Powered Content Management**<br><br>Harness the flexibility of JavaScript to define and manage your content efficiently. <br><br> - [Content declaration](https://intlayer.org/doc/concept/content)
|
|
54
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/per_locale_content_declaration_file.png?raw=true" alt="Feature" width="700"> | **Per-Locale Content Declaration File**<br><br>Speed up your development by declaring your content once, before auto generation.<br><br> - [Per-Locale Content Declaration File](https://intlayer.org/doc/concept/per-locale-file)
|
|
55
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/compiler.jpg?raw=true" alt="Feature" width="700"> | **Compiler**<br><br>The Intlayer Compiler extract automatically the content from the components and generate the dictionary files.<br><br> - [Compiler](https://intlayer.org/doc/compiler)
|
|
56
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true" alt="Feature" width="700"> | **Type-Safe Environment**<br><br>Leverage TypeScript to ensure your content definitions and code are error-free, while also benefiting from IDE autocompletion.<br><br> - [TypeScript configuration](https://intlayer.org/doc/environment/vite-and-react#configure-typescript)
|
|
57
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/config_file.png?raw=true" alt="Feature" width="700"> | **Simplified Setup**<br><br>Get up and running quickly with minimal configuration. Adjust settings for internationalization, routing, AI, build, and content handling with ease. <br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs)
|
|
58
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/content_retrieval.png?raw=true" alt="Feature" width="700"> | **Simplified Content Retrieval**<br><br>No need to call your `t` function for each piece of content. Retrieve all your content directly using a single hook.<br><br> - [React integration](https://intlayer.org/doc/environment/create-react-app)
|
|
59
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/server_component.png?raw=true" alt="Feature" width="700"> | **Consistent Server Component Implementation**<br><br>Perfectly suited for Next.js server components, use the same implementation for both client and server components, no need to pass your `t` function across each server component. <br><br> - [Server Components](https://intlayer.org/doc/environment/nextjs#step-7-utilize-content-in-your-code)
|
|
60
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/file_tree.png?raw=true" alt="Feature" width="700"> | **Organized Codebase**<br><br>Keep your codebase more organized: 1 component = 1 dictionary in the same folder. Translations close to their respective components, enhance maintainability and clarity. <br><br> - [How Intlayer works](https://intlayer.org/doc/concept/how-works-intlayer)
|
|
61
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/url_routing.png?raw=true" alt="Feature" width="700"> | **Enhanced Routing**<br><br>Full support of app routing, adapting seamlessly to complex application structures, for Next.js, React, Vite, Vue.js, etc.<br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs)
|
|
62
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/markdown.png?raw=true" alt="Feature" width="700"> | **Markdown Support**<br><br>Import and interpret, locale files and remote Markdown for multilingual content like privacy policies, documentation, etc. Interpret and make Markdown metadata accessible in your code.<br><br> - [Content files](https://intlayer.org/doc/concept/content/file)
|
|
63
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/visual_editor.png?raw=true" alt="Feature" width="700"> | **Free Visual Editor & CMS**<br><br>A free visual editor and CMS are available for content writers, removing the need for a localization platform. Keep your content synchronized using Git, or externalize it totally or partially with the CMS.<br><br> - [Intlayer Editor](https://intlayer.org/doc/concept/editor) <br> - [Intlayer CMS](https://intlayer.org/doc/concept/cms)
|
|
64
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/bundle.png?raw=true" alt="Feature" width="700"> | **Tree-shakable Content**<br><br>Tree-shakable content, reducing the size of the final bundle. Loads content per component, excluding any unused content from your bundle. Supports lazy loading to enhance app loading efficiency. <br><br> - [App build optimization](https://intlayer.org/doc/concept/how-works-intlayer#app-build-optimization)
|
|
65
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/static_rendering.png?raw=true" alt="Feature" width="700"> | **Static Rendering**<br><br>Doesn't block Static Rendering. <br><br> - [Next.js integration](https://intlayer.org/doc/environment/nextjs)
|
|
66
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/AI_translation.png?raw=true" alt="Feature" width="700"> | **AI-Powered Translation**<br><br>Transform your website into 231 languages with just one click using Intlayer's advanced AI-powered translation tools using your own AI provider / API key. <br><br> - [CI/CD integration](https://intlayer.org/doc/concept/ci-cd) <br> - [Intlayer CLI](https://intlayer.org/doc/concept/cli) <br> - [Auto fill](https://intlayer.org/doc/concept/auto-fill)
|
|
67
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/mcp.png?raw=true" alt="Feature" width="700"> | **MCP Server Integration**<br><br>Provides an MCP (Model Context Protocol) server for IDE automation, enabling seamless content management and i18n workflows directly within your development environment. <br><br> - [MCP Server](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md)
|
|
68
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/vscode_extension.png?raw=true" alt="Feature" width="700"> | **VSCode Extension**<br><br>Intlayer provides a VSCode extension to help you manage your content and translations, building your dictionaries, translating your content, and more. <br><br> - [VSCode Extension](https://intlayer.org/doc/vs-code-extension)
|
|
69
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/interoperability.png?raw=true" alt="Feature" width="700"> | **Interoperability**<br><br>Allow interoperability with react-i18next, next-i18next, next-intl, react-intl, vue-i18n. <br><br> - [Intlayer and react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer and next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer and next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer and vue-i18n](https://intlayer.org/blog/intlayer-with-vue-i18n) |
|
|
70
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/benchmark.png?raw=true" alt="Feature" width="700"> | **Performances & Benchmark**<br><br>Uses advanced tree-shaking and dynamic loading to boost performances and keep the solution as light as possible. <br><br> - [Performances & Benchmark](https://intlayer.org/doc/benchmark)
|
|
50
|
+
| Feature | Description |
|
|
51
|
+
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/frameworks.png?raw=true" alt="Feature" width="700"> | **Cross-Frameworks Support**<br><br>Intlayer is compatible with all major frameworks and libraries, including Next.js, React, Vite, Vue.js, Nuxt, Preact, Express, and more. |
|
|
53
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/javascript_content_management.jpg?raw=true" alt="Feature" width="700"> | **JavaScript-Powered Content Management**<br><br>Harness the flexibility of JavaScript to define and manage your content efficiently. <br><br> - [Content declaration](https://intlayer.org/doc/concept/content) |
|
|
54
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/per_locale_content_declaration_file.png?raw=true" alt="Feature" width="700"> | **Per-Locale Content Declaration File**<br><br>Speed up your development by declaring your content once, before auto generation.<br><br> - [Per-Locale Content Declaration File](https://intlayer.org/doc/concept/per-locale-file) |
|
|
55
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/compiler.jpg?raw=true" alt="Feature" width="700"> | **Compiler**<br><br>The Intlayer Compiler extract automatically the content from the components and generate the dictionary files.<br><br> - [Compiler](https://intlayer.org/doc/compiler) |
|
|
56
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true" alt="Feature" width="700"> | **Type-Safe Environment**<br><br>Leverage TypeScript to ensure your content definitions and code are error-free, while also benefiting from IDE autocompletion.<br><br> - [TypeScript configuration](https://intlayer.org/doc/environment/vite-and-react#configure-typescript) |
|
|
57
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/config_file.png?raw=true" alt="Feature" width="700"> | **Simplified Setup**<br><br>Get up and running quickly with minimal configuration. Adjust settings for internationalization, routing, AI, build, and content handling with ease. <br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs) |
|
|
58
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/content_retrieval.png?raw=true" alt="Feature" width="700"> | **Simplified Content Retrieval**<br><br>No need to call your `t` function for each piece of content. Retrieve all your content directly using a single hook.<br><br> - [React integration](https://intlayer.org/doc/environment/create-react-app) |
|
|
59
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/server_component.png?raw=true" alt="Feature" width="700"> | **Consistent Server Component Implementation**<br><br>Perfectly suited for Next.js server components, use the same implementation for both client and server components, no need to pass your `t` function across each server component. <br><br> - [Server Components](https://intlayer.org/doc/environment/nextjs#step-7-utilize-content-in-your-code) |
|
|
60
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/file_tree.png?raw=true" alt="Feature" width="700"> | **Organized Codebase**<br><br>Keep your codebase more organized: 1 component = 1 dictionary in the same folder. Translations close to their respective components, enhance maintainability and clarity. <br><br> - [How Intlayer works](https://intlayer.org/doc/concept/how-works-intlayer) |
|
|
61
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/url_routing.png?raw=true" alt="Feature" width="700"> | **Enhanced Routing**<br><br>Full support of app routing, adapting seamlessly to complex application structures, for Next.js, React, Vite, Vue.js, etc.<br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs) |
|
|
62
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/markdown.png?raw=true" alt="Feature" width="700"> | **Markdown Support**<br><br>Import and interpret, locale files and remote Markdown for multilingual content like privacy policies, documentation, etc. Interpret and make Markdown metadata accessible in your code.<br><br> - [Content files](https://intlayer.org/doc/concept/content/file) |
|
|
63
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/visual_editor.png?raw=true" alt="Feature" width="700"> | **Free Visual Editor & CMS**<br><br>A free visual editor and CMS are available for content writers, removing the need for a localization platform. Keep your content synchronized using Git, or externalize it totally or partially with the CMS.<br><br> - [Intlayer Editor](https://intlayer.org/doc/concept/editor) <br> - [Intlayer CMS](https://intlayer.org/doc/concept/cms) |
|
|
64
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/bundle.png?raw=true" alt="Feature" width="700"> | **Tree-shakable Content**<br><br>Tree-shakable content, reducing the size of the final bundle. Loads content per component, excluding any unused content from your bundle. Supports lazy loading to enhance app loading efficiency. <br><br> - [App build optimization](https://intlayer.org/doc/concept/how-works-intlayer#app-build-optimization) |
|
|
65
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/static_rendering.png?raw=true" alt="Feature" width="700"> | **Static Rendering**<br><br>Doesn't block Static Rendering. <br><br> - [Next.js integration](https://intlayer.org/doc/environment/nextjs) |
|
|
66
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/AI_translation.png?raw=true" alt="Feature" width="700"> | **AI-Powered Translation**<br><br>Transform your website into 231 languages with just one click using Intlayer's advanced AI-powered translation tools using your own AI provider / API key. <br><br> - [CI/CD integration](https://intlayer.org/doc/concept/ci-cd) <br> - [Intlayer CLI](https://intlayer.org/doc/concept/cli) <br> - [Auto fill](https://intlayer.org/doc/concept/auto-fill) |
|
|
67
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/mcp.png?raw=true" alt="Feature" width="700"> | **MCP Server Integration**<br><br>Provides an MCP (Model Context Protocol) server for IDE automation, enabling seamless content management and i18n workflows directly within your development environment. <br><br> - [MCP Server](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md) |
|
|
68
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/vscode_extension.png?raw=true" alt="Feature" width="700"> | **VSCode Extension**<br><br>Intlayer provides a VSCode extension to help you manage your content and translations, building your dictionaries, translating your content, and more. <br><br> - [VSCode Extension](https://intlayer.org/doc/vs-code-extension) |
|
|
69
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/interoperability.png?raw=true" alt="Feature" width="700"> | **Interoperability**<br><br>Allow interoperability with react-i18next, next-i18next, next-intl, react-intl, vue-i18n. <br><br> - [Intlayer and react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer and next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer and next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer and vue-i18n](https://intlayer.org/blog/intlayer-with-vue-i18n) <br> - [Intlayer compat adapters](https://intlayer.org/doc/compatibility) |
|
|
70
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/benchmark.png?raw=true" alt="Feature" width="700"> | **Performances & Benchmark**<br><br>Uses advanced tree-shaking and dynamic loading to boost performances and keep the solution as light as possible. <br><br> - [Performances & Benchmark](https://intlayer.org/doc/benchmark) |
|
|
71
71
|
|
|
72
72
|
---
|
|
73
73
|
|
|
@@ -162,7 +162,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
162
162
|
<li><a href="https://intlayer.org/doc/concept/cms" rel=''>Intlayer CMS</a></li>
|
|
163
163
|
<li><a href="https://intlayer.org/doc/concept/content" rel=''>Dictionary</a>
|
|
164
164
|
<ul>
|
|
165
|
-
<li><a href="https://intlayer.org/doc/concept/
|
|
165
|
+
<li><a href="https://intlayer.org/doc/concept/per-locale-file" rel=''>Per-Locale Content Declaration File</a></li>
|
|
166
166
|
<li><a href="https://intlayer.org/doc/concept/content/translation" rel=''>Translation</a></li>
|
|
167
167
|
<li><a href="https://intlayer.org/doc/concept/content/enumeration" rel=''>Enumeration</a></li>
|
|
168
168
|
<li><a href="https://intlayer.org/doc/concept/content/condition" rel=''>Condition</a></li>
|
|
@@ -183,7 +183,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
183
183
|
<ul>
|
|
184
184
|
<li><a href="https://intlayer.org/doc/environment/nextjs/15" rel=''>Next.js 15</a></li>
|
|
185
185
|
<li><a href="https://intlayer.org/doc/environment/nextjs/14" rel=''>Next.js 14 (App Router)</a></li>
|
|
186
|
-
<li><a href="https://intlayer.org/doc/environment/nextjs/next-with-
|
|
186
|
+
<li><a href="https://intlayer.org/doc/environment/nextjs/next-with-page-router" rel=''>Next.js Page Router</a></li>
|
|
187
187
|
<li><a href="https://intlayer.org/doc/environment/nextjs/compiler" rel=''>Next.js using Compiler</a></li>
|
|
188
188
|
</ul>
|
|
189
189
|
</li>
|
|
@@ -212,7 +212,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
212
212
|
<li><a href="https://intlayer.org/doc/environment/sveltekit" rel=''>SvelteKit</a></li>
|
|
213
213
|
<li><a href="https://intlayer.org/doc/environment/vite-and-preact" rel=''>Vite + Preact</a></li>
|
|
214
214
|
<li><a href="https://intlayer.org/doc/environment/vite-and-vue" rel=''>Vite + Vue</a></li>
|
|
215
|
-
<li><a href="https://intlayer.org/doc/environment/
|
|
215
|
+
<li><a href="https://intlayer.org/doc/environment/nuxt-and-vue" rel=''>Vite + Nuxt</a></li>
|
|
216
216
|
<li><a href="https://intlayer.org/doc/environment/vite-and-solid" rel=''>Vite + Solid</a></li>
|
|
217
217
|
<li><a href="https://intlayer.org/doc/environment/angular" rel=''>Angular</a></li>
|
|
218
218
|
<li>
|
|
@@ -19,11 +19,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
19
19
|
}
|
|
20
20
|
return to;
|
|
21
21
|
};
|
|
22
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
23
23
|
value: mod,
|
|
24
24
|
enumerable: true
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
|
|
27
27
|
//#endregion
|
|
28
|
-
|
|
29
28
|
exports.__toESM = __toESM;
|
|
@@ -16,8 +16,9 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
16
16
|
*/
|
|
17
17
|
const appWithTranslation = (WrappedApp, _configOverride) => {
|
|
18
18
|
const AppWithTranslation = (props) => {
|
|
19
|
+
const locale = props.pageProps?._nextI18Next?.initialLocale ?? props.router?.locale;
|
|
19
20
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_intlayer.IntlayerProvider, {
|
|
20
|
-
locale
|
|
21
|
+
locale,
|
|
21
22
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WrappedApp, { ...props })
|
|
22
23
|
});
|
|
23
24
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appWithTranslation.cjs","names":["IntlayerProvider"],"sources":["../../src/appWithTranslation.tsx"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport type { appWithTranslation as _appWithTranslation } from 'next-i18next/pages';\nimport type * as React from 'react';\nimport { IntlayerProvider } from 'react-intlayer';\n\n/**\n * Drop-in replacement for next-i18next's `appWithTranslation` HOC.\n *\n * Wraps the Next.js `App` component in `IntlayerProvider` and passes the\n * active locale from `_nextI18Next.initialLocale` or the Next.js router.\n *\n * @example\n * ```tsx\n * export default appWithTranslation(MyApp);\n * ```\n */\nexport const appWithTranslation: typeof _appWithTranslation = (\n WrappedApp,\n _configOverride?\n) => {\n const AppWithTranslation = (\n props: React.ComponentProps<typeof WrappedApp> & {\n pageProps: {\n _nextI18Next?: { initialLocale?: string };\n [key: string]: unknown;\n };\n router?: { locale?: string };\n }\n ) => {\n const locale: string | undefined =\n props.pageProps?._nextI18Next?.initialLocale ?? props.router?.locale;\n\n return (\n <IntlayerProvider locale={locale as LocalesValues}>\n <WrappedApp {...props} />\n </IntlayerProvider>\n );\n };\n\n AppWithTranslation.displayName = `appWithTranslation(${\n WrappedApp.displayName ?? WrappedApp.name ?? 'App'\n })`;\n\n return AppWithTranslation as unknown as ReturnType<\n typeof _appWithTranslation\n >;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,MAAa,sBACX,YACA,oBACG;CACH,MAAM,sBACJ,UAOG;
|
|
1
|
+
{"version":3,"file":"appWithTranslation.cjs","names":["IntlayerProvider"],"sources":["../../src/appWithTranslation.tsx"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport type { appWithTranslation as _appWithTranslation } from 'next-i18next/pages';\nimport type * as React from 'react';\nimport { IntlayerProvider } from 'react-intlayer';\n\n/**\n * Drop-in replacement for next-i18next's `appWithTranslation` HOC.\n *\n * Wraps the Next.js `App` component in `IntlayerProvider` and passes the\n * active locale from `_nextI18Next.initialLocale` or the Next.js router.\n *\n * @example\n * ```tsx\n * export default appWithTranslation(MyApp);\n * ```\n */\nexport const appWithTranslation: typeof _appWithTranslation = (\n WrappedApp,\n _configOverride?\n) => {\n const AppWithTranslation = (\n props: React.ComponentProps<typeof WrappedApp> & {\n pageProps: {\n _nextI18Next?: { initialLocale?: string };\n [key: string]: unknown;\n };\n router?: { locale?: string };\n }\n ) => {\n const locale: string | undefined =\n props.pageProps?._nextI18Next?.initialLocale ?? props.router?.locale;\n\n return (\n <IntlayerProvider locale={locale as LocalesValues}>\n <WrappedApp {...props} />\n </IntlayerProvider>\n );\n };\n\n AppWithTranslation.displayName = `appWithTranslation(${\n WrappedApp.displayName ?? WrappedApp.name ?? 'App'\n })`;\n\n return AppWithTranslation as unknown as ReturnType<\n typeof _appWithTranslation\n >;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,MAAa,sBACX,YACA,oBACG;CACH,MAAM,sBACJ,UAOG;EACH,MAAM,SACJ,MAAM,WAAW,cAAc,iBAAiB,MAAM,QAAQ;EAEhE,OACE,2CAACA,iCAAD;GAA0B;aACxB,2CAAC,YAAD,EAAY,GAAI,MAAQ;EACR;CAEtB;CAEA,mBAAmB,cAAc,sBAC/B,WAAW,eAAe,WAAW,QAAQ,MAC9C;CAED,OAAO;AAGT"}
|
|
@@ -116,7 +116,7 @@ const createNextI18nPlugin = (_i18nPath) => {
|
|
|
116
116
|
const appLogger = (0, _intlayer_config_logger.getAppLogger)(intlayerConfig);
|
|
117
117
|
(0, _intlayer_engine_utils.runOnce)((0, node_path.join)(intlayerConfig.system.baseDir, ".intlayer", "cache", "intlayer-issues-invitation.lock"), () => {
|
|
118
118
|
appLogger([(0, _intlayer_config_logger.colorize)("Please report any issues you met on GitHub:", _intlayer_config_colors.GREY), (0, _intlayer_config_logger.colorize)("https://github.com/aymericzip/intlayer/issues", _intlayer_config_colors.GREY_LIGHT)]);
|
|
119
|
-
}, { cacheTimeoutMs:
|
|
119
|
+
}, { cacheTimeoutMs: 36e5 });
|
|
120
120
|
const customWebpack = nextConfig.webpack;
|
|
121
121
|
const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({
|
|
122
122
|
request,
|
|
@@ -132,7 +132,7 @@ const createNextI18nPlugin = (_i18nPath) => {
|
|
|
132
132
|
if (typeof customWebpack === "function") return customWebpack(config, options);
|
|
133
133
|
return config;
|
|
134
134
|
} };
|
|
135
|
-
const
|
|
135
|
+
const mergedConfig = {
|
|
136
136
|
...nextConfig,
|
|
137
137
|
...aliasConfig,
|
|
138
138
|
turbopack: {
|
|
@@ -142,7 +142,8 @@ const createNextI18nPlugin = (_i18nPath) => {
|
|
|
142
142
|
...turboAlias
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
-
}
|
|
145
|
+
};
|
|
146
|
+
const finalConfig = await (0, next_intlayer_server.withIntlayer)(mergedConfig, { swcExtraCallers: NEXT_I18NEXT_SWC_CALLERS });
|
|
146
147
|
keepDictionaryRegistry(finalConfig);
|
|
147
148
|
return finalConfig;
|
|
148
149
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["sep","REACT_I18NEXT_CALLERS","ANSIColors"],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport {\n REACT_I18NEXT_CALLERS,\n toSwcExtraCallers,\n} from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { NextConfig } from 'next';\nimport { withIntlayer } from 'next-intlayer/server';\n\n/**\n * `require` that works in both the CJS and ESM builds of this plugin.\n * `import.meta.url` is rewritten to the module path in the CJS output by the\n * bundler, so `createRequire` resolves correctly in either format.\n */\nconst compatRequire = createRequire(import.meta.url);\n\n/**\n * Maps each original import specifier (next-i18next, react-i18next, i18next) to\n * the `@intlayer/*` specifier that should serve it instead.\n */\nconst ALIAS_ENTRIES: { request: string; replacement: string }[] = [\n { request: 'next-i18next', replacement: '@intlayer/next-i18next' },\n { request: 'react-i18next', replacement: '@intlayer/react-i18next' },\n { request: 'i18next', replacement: '@intlayer/i18next' },\n];\n\n/**\n * Split a package specifier into its package name and export subpath.\n *\n * @param specifier - e.g. `@intlayer/react-i18next` or `i18next`.\n * @returns `{ packageName, exportKey }` where `exportKey` is the `exports` map\n * key (`.` for the package root).\n */\nconst splitSpecifier = (\n specifier: string\n): { packageName: string; exportKey: string } => {\n const segments = specifier.split('/');\n const packageName = specifier.startsWith('@')\n ? segments.slice(0, 2).join('/')\n : (segments[0] ?? specifier);\n const subpath = specifier.slice(packageName.length);\n return { packageName, exportKey: subpath === '' ? '.' : `.${subpath}` };\n};\n\n/**\n * Resolve the absolute path of a package export, preferring the ESM (`import`)\n * condition so Turbopack and modern bundlers load the `.mjs` build (which keeps\n * the `\"use client\"` directives) rather than the CommonJS fallback.\n *\n * Both Turbopack and webpack ignore alias values that are bare package\n * specifiers, so the aliases must point at real files.\n *\n * @param specifier - Package specifier, e.g. `@intlayer/react-i18next`.\n * @returns Absolute path to the resolved module file.\n */\nconst resolveEsmPath = (specifier: string): string => {\n const { packageName, exportKey } = splitSpecifier(specifier);\n const packageJson = compatRequire(`${packageName}/package.json`) as {\n exports?: Record<\n string,\n string | { import?: string; require?: string; default?: string }\n >;\n };\n const packageDir = dirname(\n compatRequire.resolve(`${packageName}/package.json`)\n );\n\n const exportEntry = packageJson.exports?.[exportKey];\n const relativeFile =\n typeof exportEntry === 'string'\n ? exportEntry\n : (exportEntry?.import ?? exportEntry?.require ?? exportEntry?.default);\n\n // Fall back to Node resolution if the exports map is unexpected.\n if (!relativeFile) return compatRequire.resolve(specifier);\n\n return resolve(packageDir, relativeFile);\n};\n\n/**\n * Format an absolute path as a project-root-relative specifier (prefixed with\n * `./` and using forward slashes). Turbopack only honours `resolveAlias` values\n * that are project-root-relative paths — bare specifiers are ignored and\n * absolute paths are misread as root-relative. Mirrors `withIntlayer`'s\n * Turbopack alias formatter.\n *\n * @param absolutePath - Absolute path to the target module file.\n * @returns Relative specifier such as `./node_modules/@intlayer/react-i18next/...`.\n */\nconst toTurbopackAlias = (absolutePath: string): string =>\n `./${relative(process.cwd(), absolutePath).split(sep).join('/')}`;\n\n/**\n * SWC extra-caller configs derived from the shared caller registry\n * (`@intlayer/config/callers`) — the single source of truth also consumed by\n * the babel analyzer/optimizer and the LSP.\n */\nconst NEXT_I18NEXT_SWC_CALLERS = toSwcExtraCallers(REACT_I18NEXT_CALLERS);\n\n/**\n * Disables the SWC `replaceDictionaryEntry` optimization on the resolved Next.js\n * config so the runtime dictionary registry stays populated. Mutates the\n * `@intlayer/swc` plugin options in place (both webpack and Turbopack read the\n * same `experimental.swcPlugins` entry).\n *\n * @param config - The Next.js config returned by `withIntlayer`.\n */\nconst keepDictionaryRegistry = (config: NextConfig): void => {\n const swcPlugins = (\n config.experimental as { swcPlugins?: unknown[] } | undefined\n )?.swcPlugins;\n if (!Array.isArray(swcPlugins)) return;\n\n for (const plugin of swcPlugins) {\n if (!Array.isArray(plugin)) continue;\n const [pluginPath, pluginOptions] = plugin as [unknown, unknown];\n if (\n typeof pluginPath === 'string' &&\n pluginPath.includes('@intlayer/swc') &&\n pluginOptions !== null &&\n typeof pluginOptions === 'object'\n ) {\n (pluginOptions as Record<string, unknown>).replaceDictionaryEntry = false;\n }\n }\n};\n\n/**\n * A Next.js plugin for next-i18next compat that wraps next-intlayer's plugin\n * and configures resolve aliases so `next-i18next` imports are served by\n * `@intlayer/next-i18next`.\n */\nexport const createNextI18nPlugin = (_i18nPath?: string) => {\n return async (nextConfig: NextConfig = {}): Promise<NextConfig> => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig.system.baseDir,\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const customWebpack = nextConfig.webpack;\n\n const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({\n request,\n absolutePath: resolveEsmPath(replacement),\n }));\n\n // Webpack resolves aliases from absolute paths.\n const webpackAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n absolutePath,\n ])\n );\n\n // Turbopack only honours project-root-relative `./` paths.\n const turboAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n toTurbopackAlias(absolutePath),\n ])\n );\n\n const aliasConfig = {\n webpack: (config: any, options: any) => {\n config.resolve.alias = {\n ...config.resolve.alias,\n ...webpackAlias,\n };\n\n if (typeof customWebpack === 'function') {\n return customWebpack(config, options);\n }\n return config;\n },\n };\n\n const mergedConfig: NextConfig = {\n ...nextConfig,\n ...aliasConfig,\n turbopack: {\n ...(nextConfig.turbopack ?? {}),\n resolveAlias: {\n ...(nextConfig.turbopack?.resolveAlias ?? {}),\n ...turboAlias,\n },\n },\n };\n\n const finalConfig = await withIntlayer(mergedConfig, {\n swcExtraCallers: NEXT_I18NEXT_SWC_CALLERS,\n });\n\n // i18next exposes runtime namespace APIs (`i18n.getFixedT(locale, ns)`,\n // `t('ns:key')`) that resolve dictionaries at runtime through `getIntlayer`.\n // Unlike `useTranslation('ns')`, these are not statically analyzable, so the\n // SWC cannot rewrite them to direct dictionary imports. The build optimization\n // normally empties the runtime dictionary registry (`replaceDictionaryEntry`),\n // which would make those APIs fall back to raw keys on the server. Keeping the\n // registry populated restores them; statically analyzable call sites are still\n // rewritten to direct imports, so client bundles stay tree-shaken.\n keepDictionaryRegistry(finalConfig);\n\n return finalConfig;\n };\n};\n\nexport default createNextI18nPlugin;\n\n/**\n * A pre-instantiated Next.js plugin for next-i18next compat.\n * Wraps a NextConfig directly without requiring the factory call pattern.\n *\n * Usage:\n * ```ts\n * import { withI18next } from '@intlayer/next-i18next/plugin';\n * export default withI18next(nextConfig);\n * ```\n */\nexport const withI18next = createNextI18nPlugin();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["createRequire","dirname","resolve","relative","sep","toSwcExtraCallers","REACT_I18NEXT_CALLERS","getConfiguration","getAppLogger","join","colorize","ANSIColors","withIntlayer"],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport {\n REACT_I18NEXT_CALLERS,\n toSwcExtraCallers,\n} from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { NextConfig } from 'next';\nimport { withIntlayer } from 'next-intlayer/server';\n\n/**\n * `require` that works in both the CJS and ESM builds of this plugin.\n * `import.meta.url` is rewritten to the module path in the CJS output by the\n * bundler, so `createRequire` resolves correctly in either format.\n */\nconst compatRequire = createRequire(import.meta.url);\n\n/**\n * Maps each original import specifier (next-i18next, react-i18next, i18next) to\n * the `@intlayer/*` specifier that should serve it instead.\n */\nconst ALIAS_ENTRIES: { request: string; replacement: string }[] = [\n { request: 'next-i18next', replacement: '@intlayer/next-i18next' },\n { request: 'react-i18next', replacement: '@intlayer/react-i18next' },\n { request: 'i18next', replacement: '@intlayer/i18next' },\n];\n\n/**\n * Split a package specifier into its package name and export subpath.\n *\n * @param specifier - e.g. `@intlayer/react-i18next` or `i18next`.\n * @returns `{ packageName, exportKey }` where `exportKey` is the `exports` map\n * key (`.` for the package root).\n */\nconst splitSpecifier = (\n specifier: string\n): { packageName: string; exportKey: string } => {\n const segments = specifier.split('/');\n const packageName = specifier.startsWith('@')\n ? segments.slice(0, 2).join('/')\n : (segments[0] ?? specifier);\n const subpath = specifier.slice(packageName.length);\n return { packageName, exportKey: subpath === '' ? '.' : `.${subpath}` };\n};\n\n/**\n * Resolve the absolute path of a package export, preferring the ESM (`import`)\n * condition so Turbopack and modern bundlers load the `.mjs` build (which keeps\n * the `\"use client\"` directives) rather than the CommonJS fallback.\n *\n * Both Turbopack and webpack ignore alias values that are bare package\n * specifiers, so the aliases must point at real files.\n *\n * @param specifier - Package specifier, e.g. `@intlayer/react-i18next`.\n * @returns Absolute path to the resolved module file.\n */\nconst resolveEsmPath = (specifier: string): string => {\n const { packageName, exportKey } = splitSpecifier(specifier);\n const packageJson = compatRequire(`${packageName}/package.json`) as {\n exports?: Record<\n string,\n string | { import?: string; require?: string; default?: string }\n >;\n };\n const packageDir = dirname(\n compatRequire.resolve(`${packageName}/package.json`)\n );\n\n const exportEntry = packageJson.exports?.[exportKey];\n const relativeFile =\n typeof exportEntry === 'string'\n ? exportEntry\n : (exportEntry?.import ?? exportEntry?.require ?? exportEntry?.default);\n\n // Fall back to Node resolution if the exports map is unexpected.\n if (!relativeFile) return compatRequire.resolve(specifier);\n\n return resolve(packageDir, relativeFile);\n};\n\n/**\n * Format an absolute path as a project-root-relative specifier (prefixed with\n * `./` and using forward slashes). Turbopack only honours `resolveAlias` values\n * that are project-root-relative paths — bare specifiers are ignored and\n * absolute paths are misread as root-relative. Mirrors `withIntlayer`'s\n * Turbopack alias formatter.\n *\n * @param absolutePath - Absolute path to the target module file.\n * @returns Relative specifier such as `./node_modules/@intlayer/react-i18next/...`.\n */\nconst toTurbopackAlias = (absolutePath: string): string =>\n `./${relative(process.cwd(), absolutePath).split(sep).join('/')}`;\n\n/**\n * SWC extra-caller configs derived from the shared caller registry\n * (`@intlayer/config/callers`) — the single source of truth also consumed by\n * the babel analyzer/optimizer and the LSP.\n */\nconst NEXT_I18NEXT_SWC_CALLERS = toSwcExtraCallers(REACT_I18NEXT_CALLERS);\n\n/**\n * Disables the SWC `replaceDictionaryEntry` optimization on the resolved Next.js\n * config so the runtime dictionary registry stays populated. Mutates the\n * `@intlayer/swc` plugin options in place (both webpack and Turbopack read the\n * same `experimental.swcPlugins` entry).\n *\n * @param config - The Next.js config returned by `withIntlayer`.\n */\nconst keepDictionaryRegistry = (config: NextConfig): void => {\n const swcPlugins = (\n config.experimental as { swcPlugins?: unknown[] } | undefined\n )?.swcPlugins;\n if (!Array.isArray(swcPlugins)) return;\n\n for (const plugin of swcPlugins) {\n if (!Array.isArray(plugin)) continue;\n const [pluginPath, pluginOptions] = plugin as [unknown, unknown];\n if (\n typeof pluginPath === 'string' &&\n pluginPath.includes('@intlayer/swc') &&\n pluginOptions !== null &&\n typeof pluginOptions === 'object'\n ) {\n (pluginOptions as Record<string, unknown>).replaceDictionaryEntry = false;\n }\n }\n};\n\n/**\n * A Next.js plugin for next-i18next compat that wraps next-intlayer's plugin\n * and configures resolve aliases so `next-i18next` imports are served by\n * `@intlayer/next-i18next`.\n */\nexport const createNextI18nPlugin = (_i18nPath?: string) => {\n return async (nextConfig: NextConfig = {}): Promise<NextConfig> => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig.system.baseDir,\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const customWebpack = nextConfig.webpack;\n\n const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({\n request,\n absolutePath: resolveEsmPath(replacement),\n }));\n\n // Webpack resolves aliases from absolute paths.\n const webpackAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n absolutePath,\n ])\n );\n\n // Turbopack only honours project-root-relative `./` paths.\n const turboAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n toTurbopackAlias(absolutePath),\n ])\n );\n\n const aliasConfig = {\n webpack: (config: any, options: any) => {\n config.resolve.alias = {\n ...config.resolve.alias,\n ...webpackAlias,\n };\n\n if (typeof customWebpack === 'function') {\n return customWebpack(config, options);\n }\n return config;\n },\n };\n\n const mergedConfig: NextConfig = {\n ...nextConfig,\n ...aliasConfig,\n turbopack: {\n ...(nextConfig.turbopack ?? {}),\n resolveAlias: {\n ...(nextConfig.turbopack?.resolveAlias ?? {}),\n ...turboAlias,\n },\n },\n };\n\n const finalConfig = await withIntlayer(mergedConfig, {\n swcExtraCallers: NEXT_I18NEXT_SWC_CALLERS,\n });\n\n // i18next exposes runtime namespace APIs (`i18n.getFixedT(locale, ns)`,\n // `t('ns:key')`) that resolve dictionaries at runtime through `getIntlayer`.\n // Unlike `useTranslation('ns')`, these are not statically analyzable, so the\n // SWC cannot rewrite them to direct dictionary imports. The build optimization\n // normally empties the runtime dictionary registry (`replaceDictionaryEntry`),\n // which would make those APIs fall back to raw keys on the server. Keeping the\n // registry populated restores them; statically analyzable call sites are still\n // rewritten to direct imports, so client bundles stay tree-shaken.\n keepDictionaryRegistry(finalConfig);\n\n return finalConfig;\n };\n};\n\nexport default createNextI18nPlugin;\n\n/**\n * A pre-instantiated Next.js plugin for next-i18next compat.\n * Wraps a NextConfig directly without requiring the factory call pattern.\n *\n * Usage:\n * ```ts\n * import { withI18next } from '@intlayer/next-i18next/plugin';\n * export default withI18next(nextConfig);\n * ```\n */\nexport const withI18next = createNextI18nPlugin();\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverSideTranslations.cjs","names":["CYAN"],"sources":["../../src/serverSideTranslations.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { CYAN } from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\n\n/**\n * Drop-in replacement for next-i18next's `serverSideTranslations`.\n *\n * In next-i18next this function loads translation JSON files and injects\n * them as `_nextI18Next` props so `useTranslation` can hydrate on the client.\n *\n * With Intlayer all dictionaries are compiled at build time so no runtime\n * loading is needed. This function returns the minimal shape expected by\n * `appWithTranslation` / `useTranslation` for drop-in compatibility.\n *\n * @deprecated serverSideTranslations has no use case with intlayer.\n * Dictionaries are compiled at build time and loaded automatically.\n *\n * @param locale - The active locale (e.g. from `getStaticProps` context).\n * @param namespacesRequired - Namespace list; recorded but not loaded.\n * @param configOverride - Config override; recorded but not applied.\n *\n * @example\n * ```ts\n * export const getStaticProps = async ({ locale }) => ({\n * props: {\n * ...(await serverSideTranslations(locale, ['common'])),\n * },\n * });\n * ```\n */\nexport const serverSideTranslations = async (\n locale: string,\n namespacesRequired?: string[],\n configOverride?: Record<string, unknown>\n): Promise<{ _nextI18Next: Record<string, unknown> }> => {\n if (process.env.NODE_ENV === 'development') {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize('serverSideTranslations', CYAN)} has no use case with intlayer. Dictionaries are compiled at build time and loaded automatically under the hood.`\n );\n }\n\n return {\n _nextI18Next: {\n initialLocale: locale,\n initialI18nStore: {},\n ns: namespacesRequired ?? ['common'],\n userConfig: configOverride ?? null,\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAa,yBAAyB,OACpC,QACA,oBACA,mBACuD;CACvD,IAAI,QAAQ,IAAI,aAAa,eAE3B,
|
|
1
|
+
{"version":3,"file":"serverSideTranslations.cjs","names":["getAppLogger","colorize","CYAN"],"sources":["../../src/serverSideTranslations.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { CYAN } from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\n\n/**\n * Drop-in replacement for next-i18next's `serverSideTranslations`.\n *\n * In next-i18next this function loads translation JSON files and injects\n * them as `_nextI18Next` props so `useTranslation` can hydrate on the client.\n *\n * With Intlayer all dictionaries are compiled at build time so no runtime\n * loading is needed. This function returns the minimal shape expected by\n * `appWithTranslation` / `useTranslation` for drop-in compatibility.\n *\n * @deprecated serverSideTranslations has no use case with intlayer.\n * Dictionaries are compiled at build time and loaded automatically.\n *\n * @param locale - The active locale (e.g. from `getStaticProps` context).\n * @param namespacesRequired - Namespace list; recorded but not loaded.\n * @param configOverride - Config override; recorded but not applied.\n *\n * @example\n * ```ts\n * export const getStaticProps = async ({ locale }) => ({\n * props: {\n * ...(await serverSideTranslations(locale, ['common'])),\n * },\n * });\n * ```\n */\nexport const serverSideTranslations = async (\n locale: string,\n namespacesRequired?: string[],\n configOverride?: Record<string, unknown>\n): Promise<{ _nextI18Next: Record<string, unknown> }> => {\n if (process.env.NODE_ENV === 'development') {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize('serverSideTranslations', CYAN)} has no use case with intlayer. Dictionaries are compiled at build time and loaded automatically under the hood.`\n );\n }\n\n return {\n _nextI18Next: {\n initialLocale: locale,\n initialI18nStore: {},\n ns: namespacesRequired ?? ['common'],\n userConfig: configOverride ?? null,\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAa,yBAAyB,OACpC,QACA,oBACA,mBACuD;CACvD,IAAI,QAAQ,IAAI,aAAa,eAE3B,IADkBA,sCAAa,EAAE,gCAAI,CAC7B,CAAC,CACP,OAAGC,kCAAS,0BAA0BC,4BAAI,EAAE,iHAC9C;CAGF,OAAO,EACL,cAAc;EACZ,eAAe;EACf,kBAAkB,CAAC;EACnB,IAAI,sBAAsB,CAAC,QAAQ;EACnC,YAAY,kBAAkB;CAChC,EACF;AACF"}
|
|
@@ -15,8 +15,9 @@ import { jsx } from "react/jsx-runtime";
|
|
|
15
15
|
*/
|
|
16
16
|
const appWithTranslation = (WrappedApp, _configOverride) => {
|
|
17
17
|
const AppWithTranslation = (props) => {
|
|
18
|
+
const locale = props.pageProps?._nextI18Next?.initialLocale ?? props.router?.locale;
|
|
18
19
|
return /* @__PURE__ */ jsx(IntlayerProvider, {
|
|
19
|
-
locale
|
|
20
|
+
locale,
|
|
20
21
|
children: /* @__PURE__ */ jsx(WrappedApp, { ...props })
|
|
21
22
|
});
|
|
22
23
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appWithTranslation.mjs","names":[],"sources":["../../src/appWithTranslation.tsx"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport type { appWithTranslation as _appWithTranslation } from 'next-i18next/pages';\nimport type * as React from 'react';\nimport { IntlayerProvider } from 'react-intlayer';\n\n/**\n * Drop-in replacement for next-i18next's `appWithTranslation` HOC.\n *\n * Wraps the Next.js `App` component in `IntlayerProvider` and passes the\n * active locale from `_nextI18Next.initialLocale` or the Next.js router.\n *\n * @example\n * ```tsx\n * export default appWithTranslation(MyApp);\n * ```\n */\nexport const appWithTranslation: typeof _appWithTranslation = (\n WrappedApp,\n _configOverride?\n) => {\n const AppWithTranslation = (\n props: React.ComponentProps<typeof WrappedApp> & {\n pageProps: {\n _nextI18Next?: { initialLocale?: string };\n [key: string]: unknown;\n };\n router?: { locale?: string };\n }\n ) => {\n const locale: string | undefined =\n props.pageProps?._nextI18Next?.initialLocale ?? props.router?.locale;\n\n return (\n <IntlayerProvider locale={locale as LocalesValues}>\n <WrappedApp {...props} />\n </IntlayerProvider>\n );\n };\n\n AppWithTranslation.displayName = `appWithTranslation(${\n WrappedApp.displayName ?? WrappedApp.name ?? 'App'\n })`;\n\n return AppWithTranslation as unknown as ReturnType<\n typeof _appWithTranslation\n >;\n};\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,MAAa,sBACX,YACA,oBACG;CACH,MAAM,sBACJ,UAOG;
|
|
1
|
+
{"version":3,"file":"appWithTranslation.mjs","names":[],"sources":["../../src/appWithTranslation.tsx"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport type { appWithTranslation as _appWithTranslation } from 'next-i18next/pages';\nimport type * as React from 'react';\nimport { IntlayerProvider } from 'react-intlayer';\n\n/**\n * Drop-in replacement for next-i18next's `appWithTranslation` HOC.\n *\n * Wraps the Next.js `App` component in `IntlayerProvider` and passes the\n * active locale from `_nextI18Next.initialLocale` or the Next.js router.\n *\n * @example\n * ```tsx\n * export default appWithTranslation(MyApp);\n * ```\n */\nexport const appWithTranslation: typeof _appWithTranslation = (\n WrappedApp,\n _configOverride?\n) => {\n const AppWithTranslation = (\n props: React.ComponentProps<typeof WrappedApp> & {\n pageProps: {\n _nextI18Next?: { initialLocale?: string };\n [key: string]: unknown;\n };\n router?: { locale?: string };\n }\n ) => {\n const locale: string | undefined =\n props.pageProps?._nextI18Next?.initialLocale ?? props.router?.locale;\n\n return (\n <IntlayerProvider locale={locale as LocalesValues}>\n <WrappedApp {...props} />\n </IntlayerProvider>\n );\n };\n\n AppWithTranslation.displayName = `appWithTranslation(${\n WrappedApp.displayName ?? WrappedApp.name ?? 'App'\n })`;\n\n return AppWithTranslation as unknown as ReturnType<\n typeof _appWithTranslation\n >;\n};\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,MAAa,sBACX,YACA,oBACG;CACH,MAAM,sBACJ,UAOG;EACH,MAAM,SACJ,MAAM,WAAW,cAAc,iBAAiB,MAAM,QAAQ;EAEhE,OACE,oBAAC,kBAAD;GAA0B;aACxB,oBAAC,YAAD,EAAY,GAAI,MAAQ;EACR;CAEtB;CAEA,mBAAmB,cAAc,sBAC/B,WAAW,eAAe,WAAW,QAAQ,MAC9C;CAED,OAAO;AAGT"}
|
|
@@ -113,7 +113,7 @@ const createNextI18nPlugin = (_i18nPath) => {
|
|
|
113
113
|
const appLogger = getAppLogger(intlayerConfig);
|
|
114
114
|
runOnce(join(intlayerConfig.system.baseDir, ".intlayer", "cache", "intlayer-issues-invitation.lock"), () => {
|
|
115
115
|
appLogger([colorize("Please report any issues you met on GitHub:", ANSIColors.GREY), colorize("https://github.com/aymericzip/intlayer/issues", ANSIColors.GREY_LIGHT)]);
|
|
116
|
-
}, { cacheTimeoutMs:
|
|
116
|
+
}, { cacheTimeoutMs: 36e5 });
|
|
117
117
|
const customWebpack = nextConfig.webpack;
|
|
118
118
|
const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({
|
|
119
119
|
request,
|
|
@@ -129,7 +129,7 @@ const createNextI18nPlugin = (_i18nPath) => {
|
|
|
129
129
|
if (typeof customWebpack === "function") return customWebpack(config, options);
|
|
130
130
|
return config;
|
|
131
131
|
} };
|
|
132
|
-
const
|
|
132
|
+
const mergedConfig = {
|
|
133
133
|
...nextConfig,
|
|
134
134
|
...aliasConfig,
|
|
135
135
|
turbopack: {
|
|
@@ -139,7 +139,8 @@ const createNextI18nPlugin = (_i18nPath) => {
|
|
|
139
139
|
...turboAlias
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
-
}
|
|
142
|
+
};
|
|
143
|
+
const finalConfig = await withIntlayer(mergedConfig, { swcExtraCallers: NEXT_I18NEXT_SWC_CALLERS });
|
|
143
144
|
keepDictionaryRegistry(finalConfig);
|
|
144
145
|
return finalConfig;
|
|
145
146
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport {\n REACT_I18NEXT_CALLERS,\n toSwcExtraCallers,\n} from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { NextConfig } from 'next';\nimport { withIntlayer } from 'next-intlayer/server';\n\n/**\n * `require` that works in both the CJS and ESM builds of this plugin.\n * `import.meta.url` is rewritten to the module path in the CJS output by the\n * bundler, so `createRequire` resolves correctly in either format.\n */\nconst compatRequire = createRequire(import.meta.url);\n\n/**\n * Maps each original import specifier (next-i18next, react-i18next, i18next) to\n * the `@intlayer/*` specifier that should serve it instead.\n */\nconst ALIAS_ENTRIES: { request: string; replacement: string }[] = [\n { request: 'next-i18next', replacement: '@intlayer/next-i18next' },\n { request: 'react-i18next', replacement: '@intlayer/react-i18next' },\n { request: 'i18next', replacement: '@intlayer/i18next' },\n];\n\n/**\n * Split a package specifier into its package name and export subpath.\n *\n * @param specifier - e.g. `@intlayer/react-i18next` or `i18next`.\n * @returns `{ packageName, exportKey }` where `exportKey` is the `exports` map\n * key (`.` for the package root).\n */\nconst splitSpecifier = (\n specifier: string\n): { packageName: string; exportKey: string } => {\n const segments = specifier.split('/');\n const packageName = specifier.startsWith('@')\n ? segments.slice(0, 2).join('/')\n : (segments[0] ?? specifier);\n const subpath = specifier.slice(packageName.length);\n return { packageName, exportKey: subpath === '' ? '.' : `.${subpath}` };\n};\n\n/**\n * Resolve the absolute path of a package export, preferring the ESM (`import`)\n * condition so Turbopack and modern bundlers load the `.mjs` build (which keeps\n * the `\"use client\"` directives) rather than the CommonJS fallback.\n *\n * Both Turbopack and webpack ignore alias values that are bare package\n * specifiers, so the aliases must point at real files.\n *\n * @param specifier - Package specifier, e.g. `@intlayer/react-i18next`.\n * @returns Absolute path to the resolved module file.\n */\nconst resolveEsmPath = (specifier: string): string => {\n const { packageName, exportKey } = splitSpecifier(specifier);\n const packageJson = compatRequire(`${packageName}/package.json`) as {\n exports?: Record<\n string,\n string | { import?: string; require?: string; default?: string }\n >;\n };\n const packageDir = dirname(\n compatRequire.resolve(`${packageName}/package.json`)\n );\n\n const exportEntry = packageJson.exports?.[exportKey];\n const relativeFile =\n typeof exportEntry === 'string'\n ? exportEntry\n : (exportEntry?.import ?? exportEntry?.require ?? exportEntry?.default);\n\n // Fall back to Node resolution if the exports map is unexpected.\n if (!relativeFile) return compatRequire.resolve(specifier);\n\n return resolve(packageDir, relativeFile);\n};\n\n/**\n * Format an absolute path as a project-root-relative specifier (prefixed with\n * `./` and using forward slashes). Turbopack only honours `resolveAlias` values\n * that are project-root-relative paths — bare specifiers are ignored and\n * absolute paths are misread as root-relative. Mirrors `withIntlayer`'s\n * Turbopack alias formatter.\n *\n * @param absolutePath - Absolute path to the target module file.\n * @returns Relative specifier such as `./node_modules/@intlayer/react-i18next/...`.\n */\nconst toTurbopackAlias = (absolutePath: string): string =>\n `./${relative(process.cwd(), absolutePath).split(sep).join('/')}`;\n\n/**\n * SWC extra-caller configs derived from the shared caller registry\n * (`@intlayer/config/callers`) — the single source of truth also consumed by\n * the babel analyzer/optimizer and the LSP.\n */\nconst NEXT_I18NEXT_SWC_CALLERS = toSwcExtraCallers(REACT_I18NEXT_CALLERS);\n\n/**\n * Disables the SWC `replaceDictionaryEntry` optimization on the resolved Next.js\n * config so the runtime dictionary registry stays populated. Mutates the\n * `@intlayer/swc` plugin options in place (both webpack and Turbopack read the\n * same `experimental.swcPlugins` entry).\n *\n * @param config - The Next.js config returned by `withIntlayer`.\n */\nconst keepDictionaryRegistry = (config: NextConfig): void => {\n const swcPlugins = (\n config.experimental as { swcPlugins?: unknown[] } | undefined\n )?.swcPlugins;\n if (!Array.isArray(swcPlugins)) return;\n\n for (const plugin of swcPlugins) {\n if (!Array.isArray(plugin)) continue;\n const [pluginPath, pluginOptions] = plugin as [unknown, unknown];\n if (\n typeof pluginPath === 'string' &&\n pluginPath.includes('@intlayer/swc') &&\n pluginOptions !== null &&\n typeof pluginOptions === 'object'\n ) {\n (pluginOptions as Record<string, unknown>).replaceDictionaryEntry = false;\n }\n }\n};\n\n/**\n * A Next.js plugin for next-i18next compat that wraps next-intlayer's plugin\n * and configures resolve aliases so `next-i18next` imports are served by\n * `@intlayer/next-i18next`.\n */\nexport const createNextI18nPlugin = (_i18nPath?: string) => {\n return async (nextConfig: NextConfig = {}): Promise<NextConfig> => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig.system.baseDir,\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const customWebpack = nextConfig.webpack;\n\n const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({\n request,\n absolutePath: resolveEsmPath(replacement),\n }));\n\n // Webpack resolves aliases from absolute paths.\n const webpackAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n absolutePath,\n ])\n );\n\n // Turbopack only honours project-root-relative `./` paths.\n const turboAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n toTurbopackAlias(absolutePath),\n ])\n );\n\n const aliasConfig = {\n webpack: (config: any, options: any) => {\n config.resolve.alias = {\n ...config.resolve.alias,\n ...webpackAlias,\n };\n\n if (typeof customWebpack === 'function') {\n return customWebpack(config, options);\n }\n return config;\n },\n };\n\n const mergedConfig: NextConfig = {\n ...nextConfig,\n ...aliasConfig,\n turbopack: {\n ...(nextConfig.turbopack ?? {}),\n resolveAlias: {\n ...(nextConfig.turbopack?.resolveAlias ?? {}),\n ...turboAlias,\n },\n },\n };\n\n const finalConfig = await withIntlayer(mergedConfig, {\n swcExtraCallers: NEXT_I18NEXT_SWC_CALLERS,\n });\n\n // i18next exposes runtime namespace APIs (`i18n.getFixedT(locale, ns)`,\n // `t('ns:key')`) that resolve dictionaries at runtime through `getIntlayer`.\n // Unlike `useTranslation('ns')`, these are not statically analyzable, so the\n // SWC cannot rewrite them to direct dictionary imports. The build optimization\n // normally empties the runtime dictionary registry (`replaceDictionaryEntry`),\n // which would make those APIs fall back to raw keys on the server. Keeping the\n // registry populated restores them; statically analyzable call sites are still\n // rewritten to direct imports, so client bundles stay tree-shaken.\n keepDictionaryRegistry(finalConfig);\n\n return finalConfig;\n };\n};\n\nexport default createNextI18nPlugin;\n\n/**\n * A pre-instantiated Next.js plugin for next-i18next compat.\n * Wraps a NextConfig directly without requiring the factory call pattern.\n *\n * Usage:\n * ```ts\n * import { withI18next } from '@intlayer/next-i18next/plugin';\n * export default withI18next(nextConfig);\n * ```\n */\nexport const withI18next = createNextI18nPlugin();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport {\n REACT_I18NEXT_CALLERS,\n toSwcExtraCallers,\n} from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { NextConfig } from 'next';\nimport { withIntlayer } from 'next-intlayer/server';\n\n/**\n * `require` that works in both the CJS and ESM builds of this plugin.\n * `import.meta.url` is rewritten to the module path in the CJS output by the\n * bundler, so `createRequire` resolves correctly in either format.\n */\nconst compatRequire = createRequire(import.meta.url);\n\n/**\n * Maps each original import specifier (next-i18next, react-i18next, i18next) to\n * the `@intlayer/*` specifier that should serve it instead.\n */\nconst ALIAS_ENTRIES: { request: string; replacement: string }[] = [\n { request: 'next-i18next', replacement: '@intlayer/next-i18next' },\n { request: 'react-i18next', replacement: '@intlayer/react-i18next' },\n { request: 'i18next', replacement: '@intlayer/i18next' },\n];\n\n/**\n * Split a package specifier into its package name and export subpath.\n *\n * @param specifier - e.g. `@intlayer/react-i18next` or `i18next`.\n * @returns `{ packageName, exportKey }` where `exportKey` is the `exports` map\n * key (`.` for the package root).\n */\nconst splitSpecifier = (\n specifier: string\n): { packageName: string; exportKey: string } => {\n const segments = specifier.split('/');\n const packageName = specifier.startsWith('@')\n ? segments.slice(0, 2).join('/')\n : (segments[0] ?? specifier);\n const subpath = specifier.slice(packageName.length);\n return { packageName, exportKey: subpath === '' ? '.' : `.${subpath}` };\n};\n\n/**\n * Resolve the absolute path of a package export, preferring the ESM (`import`)\n * condition so Turbopack and modern bundlers load the `.mjs` build (which keeps\n * the `\"use client\"` directives) rather than the CommonJS fallback.\n *\n * Both Turbopack and webpack ignore alias values that are bare package\n * specifiers, so the aliases must point at real files.\n *\n * @param specifier - Package specifier, e.g. `@intlayer/react-i18next`.\n * @returns Absolute path to the resolved module file.\n */\nconst resolveEsmPath = (specifier: string): string => {\n const { packageName, exportKey } = splitSpecifier(specifier);\n const packageJson = compatRequire(`${packageName}/package.json`) as {\n exports?: Record<\n string,\n string | { import?: string; require?: string; default?: string }\n >;\n };\n const packageDir = dirname(\n compatRequire.resolve(`${packageName}/package.json`)\n );\n\n const exportEntry = packageJson.exports?.[exportKey];\n const relativeFile =\n typeof exportEntry === 'string'\n ? exportEntry\n : (exportEntry?.import ?? exportEntry?.require ?? exportEntry?.default);\n\n // Fall back to Node resolution if the exports map is unexpected.\n if (!relativeFile) return compatRequire.resolve(specifier);\n\n return resolve(packageDir, relativeFile);\n};\n\n/**\n * Format an absolute path as a project-root-relative specifier (prefixed with\n * `./` and using forward slashes). Turbopack only honours `resolveAlias` values\n * that are project-root-relative paths — bare specifiers are ignored and\n * absolute paths are misread as root-relative. Mirrors `withIntlayer`'s\n * Turbopack alias formatter.\n *\n * @param absolutePath - Absolute path to the target module file.\n * @returns Relative specifier such as `./node_modules/@intlayer/react-i18next/...`.\n */\nconst toTurbopackAlias = (absolutePath: string): string =>\n `./${relative(process.cwd(), absolutePath).split(sep).join('/')}`;\n\n/**\n * SWC extra-caller configs derived from the shared caller registry\n * (`@intlayer/config/callers`) — the single source of truth also consumed by\n * the babel analyzer/optimizer and the LSP.\n */\nconst NEXT_I18NEXT_SWC_CALLERS = toSwcExtraCallers(REACT_I18NEXT_CALLERS);\n\n/**\n * Disables the SWC `replaceDictionaryEntry` optimization on the resolved Next.js\n * config so the runtime dictionary registry stays populated. Mutates the\n * `@intlayer/swc` plugin options in place (both webpack and Turbopack read the\n * same `experimental.swcPlugins` entry).\n *\n * @param config - The Next.js config returned by `withIntlayer`.\n */\nconst keepDictionaryRegistry = (config: NextConfig): void => {\n const swcPlugins = (\n config.experimental as { swcPlugins?: unknown[] } | undefined\n )?.swcPlugins;\n if (!Array.isArray(swcPlugins)) return;\n\n for (const plugin of swcPlugins) {\n if (!Array.isArray(plugin)) continue;\n const [pluginPath, pluginOptions] = plugin as [unknown, unknown];\n if (\n typeof pluginPath === 'string' &&\n pluginPath.includes('@intlayer/swc') &&\n pluginOptions !== null &&\n typeof pluginOptions === 'object'\n ) {\n (pluginOptions as Record<string, unknown>).replaceDictionaryEntry = false;\n }\n }\n};\n\n/**\n * A Next.js plugin for next-i18next compat that wraps next-intlayer's plugin\n * and configures resolve aliases so `next-i18next` imports are served by\n * `@intlayer/next-i18next`.\n */\nexport const createNextI18nPlugin = (_i18nPath?: string) => {\n return async (nextConfig: NextConfig = {}): Promise<NextConfig> => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig.system.baseDir,\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const customWebpack = nextConfig.webpack;\n\n const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({\n request,\n absolutePath: resolveEsmPath(replacement),\n }));\n\n // Webpack resolves aliases from absolute paths.\n const webpackAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n absolutePath,\n ])\n );\n\n // Turbopack only honours project-root-relative `./` paths.\n const turboAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n toTurbopackAlias(absolutePath),\n ])\n );\n\n const aliasConfig = {\n webpack: (config: any, options: any) => {\n config.resolve.alias = {\n ...config.resolve.alias,\n ...webpackAlias,\n };\n\n if (typeof customWebpack === 'function') {\n return customWebpack(config, options);\n }\n return config;\n },\n };\n\n const mergedConfig: NextConfig = {\n ...nextConfig,\n ...aliasConfig,\n turbopack: {\n ...(nextConfig.turbopack ?? {}),\n resolveAlias: {\n ...(nextConfig.turbopack?.resolveAlias ?? {}),\n ...turboAlias,\n },\n },\n };\n\n const finalConfig = await withIntlayer(mergedConfig, {\n swcExtraCallers: NEXT_I18NEXT_SWC_CALLERS,\n });\n\n // i18next exposes runtime namespace APIs (`i18n.getFixedT(locale, ns)`,\n // `t('ns:key')`) that resolve dictionaries at runtime through `getIntlayer`.\n // Unlike `useTranslation('ns')`, these are not statically analyzable, so the\n // SWC cannot rewrite them to direct dictionary imports. The build optimization\n // normally empties the runtime dictionary registry (`replaceDictionaryEntry`),\n // which would make those APIs fall back to raw keys on the server. Keeping the\n // registry populated restores them; statically analyzable call sites are still\n // rewritten to direct imports, so client bundles stay tree-shaken.\n keepDictionaryRegistry(finalConfig);\n\n return finalConfig;\n };\n};\n\nexport default createNextI18nPlugin;\n\n/**\n * A pre-instantiated Next.js plugin for next-i18next compat.\n * Wraps a NextConfig directly without requiring the factory call pattern.\n *\n * Usage:\n * ```ts\n * import { withI18next } from '@intlayer/next-i18next/plugin';\n * export default withI18next(nextConfig);\n * ```\n */\nexport const withI18next = createNextI18nPlugin();\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/next-i18next",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.3.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "next-i18next API adapter for intlayer — serverSideTranslations, appWithTranslation, useTranslation backed by next-intlayer",
|
|
6
6
|
"keywords": [
|
|
@@ -79,17 +79,17 @@
|
|
|
79
79
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
|
-
"@intlayer/config": "9.
|
|
83
|
-
"@intlayer/core": "9.
|
|
84
|
-
"@intlayer/engine": "9.
|
|
85
|
-
"@intlayer/i18next": "9.
|
|
86
|
-
"@intlayer/react-i18next": "9.
|
|
87
|
-
"@intlayer/types": "9.
|
|
88
|
-
"next-intlayer": "9.
|
|
89
|
-
"react-intlayer": "9.
|
|
82
|
+
"@intlayer/config": "9.3.1",
|
|
83
|
+
"@intlayer/core": "9.3.1",
|
|
84
|
+
"@intlayer/engine": "9.3.1",
|
|
85
|
+
"@intlayer/i18next": "9.3.1",
|
|
86
|
+
"@intlayer/react-i18next": "9.3.1",
|
|
87
|
+
"@intlayer/types": "9.3.1",
|
|
88
|
+
"next-intlayer": "9.3.1",
|
|
89
|
+
"react-intlayer": "9.3.1"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
|
-
"@types/node": "26.
|
|
92
|
+
"@types/node": "26.2.0",
|
|
93
93
|
"@types/react": "19.2.18",
|
|
94
94
|
"@utils/ts-config": "1.0.4",
|
|
95
95
|
"@utils/ts-config-types": "1.0.4",
|