next-intlayer 2.0.0 → 2.0.2
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 +40 -8
- package/dist/cjs/client/IntlayerClientProvider.cjs +36 -0
- package/dist/cjs/client/IntlayerClientProvider.cjs.map +1 -0
- package/dist/cjs/client/IntlayerClientProvider.d.ts +7 -0
- package/dist/cjs/client/index.cjs +4 -3
- package/dist/cjs/client/index.cjs.map +1 -1
- package/dist/cjs/client/index.d.ts +3 -1
- package/dist/cjs/client/useLocale.cjs +0 -2
- package/dist/cjs/client/useLocale.cjs.map +1 -1
- package/dist/cjs/client/useLocale.d.ts +0 -1
- package/dist/cjs/index.cjs +5 -5
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/middleware/intlayerMiddleware.cjs +1 -2
- package/dist/cjs/middleware/intlayerMiddleware.cjs.map +1 -1
- package/dist/cjs/server/withIntlayer.cjs +7 -4
- package/dist/cjs/server/withIntlayer.cjs.map +1 -1
- package/dist/cjs/server/withIntlayer.d.ts +1 -2
- package/dist/esm/client/IntlayerClientProvider.d.mts +7 -0
- package/dist/esm/client/IntlayerClientProvider.mjs +12 -0
- package/dist/esm/client/IntlayerClientProvider.mjs.map +1 -0
- package/dist/esm/client/index.d.mts +3 -1
- package/dist/esm/client/index.mjs +5 -3
- package/dist/esm/client/index.mjs.map +1 -1
- package/dist/esm/client/useLocale.d.mts +0 -1
- package/dist/esm/client/useLocale.mjs +0 -2
- package/dist/esm/client/useLocale.mjs.map +1 -1
- package/dist/esm/index.d.mts +2 -1
- package/dist/esm/index.mjs +6 -4
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/middleware/intlayerMiddleware.mjs +1 -2
- package/dist/esm/middleware/intlayerMiddleware.mjs.map +1 -1
- package/dist/esm/server/withIntlayer.d.mts +1 -2
- package/dist/esm/server/withIntlayer.mjs +7 -4
- package/dist/esm/server/withIntlayer.mjs.map +1 -1
- package/package.json +16 -18
- package/src/index.ts +7 -3
- package/src/client/index.ts +0 -9
- package/src/client/useLocale.ts +0 -44
- package/src/generateStaticParams.ts +0 -5
- package/src/middleware/index.ts +0 -1
- package/src/middleware/intlayerMiddleware.ts +0 -232
- package/src/middleware/localeDetector.ts +0 -33
- package/src/server/index.ts +0 -9
- package/src/server/withIntlayer.ts +0 -87
- package/src/types/NextPage.ts +0 -10
- package/src/types/index.ts +0 -1
package/README.md
CHANGED
|
@@ -63,15 +63,47 @@ Implement dynamic routing for localized content:
|
|
|
63
63
|
|
|
64
64
|
Change `src/app/page.ts` to `src/app/[locale]/page.ts`
|
|
65
65
|
|
|
66
|
+
Then, implement the generateStaticParams function in your application Layout.
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
// src/app/layout.tsx
|
|
70
|
+
|
|
71
|
+
import type { Metadata } from "next";
|
|
72
|
+
import { Inter } from "next/font/google";
|
|
73
|
+
import type { ReactNode } from "react";
|
|
74
|
+
import "./globals.css";
|
|
75
|
+
|
|
76
|
+
const inter = Inter({ subsets: ["latin"] });
|
|
77
|
+
|
|
78
|
+
export { generateStaticParams } from "next-intlayer"; // Line to insert
|
|
79
|
+
|
|
80
|
+
export const metadata: Metadata = {
|
|
81
|
+
title: "Create Next App",
|
|
82
|
+
description: "Generated by create next app",
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const RootLayout = ({
|
|
86
|
+
children,
|
|
87
|
+
}: Readonly<{
|
|
88
|
+
children: ReactNode;
|
|
89
|
+
}>) => (
|
|
90
|
+
<html lang="en">
|
|
91
|
+
<body className={inter.className}>{children}</body>
|
|
92
|
+
</html>
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
export default RootLayout;
|
|
96
|
+
```
|
|
97
|
+
|
|
66
98
|
### Step 5: Manage Your Content
|
|
67
99
|
|
|
68
100
|
Create and manage your content dictionaries:
|
|
69
101
|
|
|
70
102
|
```tsx
|
|
71
103
|
// src/app/[locale]/page.content.ts
|
|
72
|
-
import { t, type
|
|
104
|
+
import { t, type DeclarationContent } from "intlayer";
|
|
73
105
|
|
|
74
|
-
const pageContent:
|
|
106
|
+
const pageContent: DeclarationContent = {
|
|
75
107
|
id: "page",
|
|
76
108
|
getStarted: {
|
|
77
109
|
main: t({
|
|
@@ -86,7 +118,7 @@ const pageContent: ContentModule = {
|
|
|
86
118
|
export default pageContent;
|
|
87
119
|
```
|
|
88
120
|
|
|
89
|
-
[See how to declare your Intlayer declaration files](https://github.com/aypineau/intlayer/blob/main/packages/intlayer/
|
|
121
|
+
[See how to declare your Intlayer declaration files](https://github.com/aypineau/intlayer/blob/main/packages/intlayer/readme_en.md).
|
|
90
122
|
|
|
91
123
|
### Step 6: Utilize Intlayer in Your Code
|
|
92
124
|
|
|
@@ -99,7 +131,7 @@ import { ClientComponentExample } from "@component/components/ClientComponentExa
|
|
|
99
131
|
import { LocaleSwitcher } from "@component/components/LangSwitcherDropDown";
|
|
100
132
|
import { NestedServerComponentExample } from "@component/components/NestedServerComponentExample";
|
|
101
133
|
import { ServerComponentExample } from "@component/components/ServerComponentExample";
|
|
102
|
-
import { type NextPageIntlayer,
|
|
134
|
+
import { type NextPageIntlayer, IntlayerProvider } from "next-intlayer";
|
|
103
135
|
import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";
|
|
104
136
|
|
|
105
137
|
const Page: NextPageIntlayer = ({ params: { locale } }) => {
|
|
@@ -119,12 +151,12 @@ const Page: NextPageIntlayer = ({ params: { locale } }) => {
|
|
|
119
151
|
<ServerComponentExample />
|
|
120
152
|
</IntlayerServerProvider>
|
|
121
153
|
{/**
|
|
122
|
-
*
|
|
154
|
+
* IntlayerProvider is used to provide the locale to the client children
|
|
123
155
|
* Can be set in any parent component, including the layout
|
|
124
156
|
*/}
|
|
125
|
-
<
|
|
157
|
+
<IntlayerProvider locale={locale}>
|
|
126
158
|
<ClientComponentExample />
|
|
127
|
-
</
|
|
159
|
+
</IntlayerProvider>
|
|
128
160
|
</>
|
|
129
161
|
);
|
|
130
162
|
};
|
|
@@ -192,7 +224,7 @@ const config: IntlayerConfig = {
|
|
|
192
224
|
export default config;
|
|
193
225
|
```
|
|
194
226
|
|
|
195
|
-
To see all available parameters, refer to the [configuration documentation here](https://github.com/aypineau/intlayer/blob/main/docs/
|
|
227
|
+
To see all available parameters, refer to the [configuration documentation here](https://github.com/aypineau/intlayer/blob/main/docs/docs/configuration_en.md).
|
|
196
228
|
|
|
197
229
|
---
|
|
198
230
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var IntlayerClientProvider_exports = {};
|
|
21
|
+
__export(IntlayerClientProvider_exports, {
|
|
22
|
+
IntlayerClientProvider: () => IntlayerClientProvider
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(IntlayerClientProvider_exports);
|
|
25
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
26
|
+
var import_react_intlayer = require("react-intlayer");
|
|
27
|
+
var import_useLocale = require('./useLocale.cjs');
|
|
28
|
+
const IntlayerClientProvider = (props) => {
|
|
29
|
+
const { setLocale } = (0, import_useLocale.useLocale)();
|
|
30
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_intlayer.IntlayerProvider, { setLocale, ...props });
|
|
31
|
+
};
|
|
32
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
33
|
+
0 && (module.exports = {
|
|
34
|
+
IntlayerClientProvider
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=IntlayerClientProvider.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/client/IntlayerClientProvider.tsx"],"sourcesContent":["'use client';\n\nimport type { FC } from 'react';\nimport { IntlayerProvider, type IntlayerProviderProps } from 'react-intlayer';\nimport { useLocale } from './useLocale';\n\nexport type IntlayerClientProviderProps = IntlayerProviderProps;\n\nexport const IntlayerClientProvider: FC<IntlayerProviderProps> = (props) => {\n const { setLocale } = useLocale();\n return <IntlayerProvider setLocale={setLocale} {...props} />;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUS;AAPT,4BAA6D;AAC7D,uBAA0B;AAInB,MAAM,yBAAoD,CAAC,UAAU;AAC1E,QAAM,EAAE,UAAU,QAAI,4BAAU;AAChC,SAAO,4CAAC,0CAAiB,WAAuB,GAAG,OAAO;AAC5D;","names":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { IntlayerProviderProps } from 'react-intlayer';
|
|
3
|
+
|
|
4
|
+
type IntlayerClientProviderProps = IntlayerProviderProps;
|
|
5
|
+
declare const IntlayerClientProvider: FC<IntlayerProviderProps>;
|
|
6
|
+
|
|
7
|
+
export { IntlayerClientProvider, type IntlayerClientProviderProps };
|
|
@@ -18,8 +18,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var client_exports = {};
|
|
20
20
|
__export(client_exports, {
|
|
21
|
-
|
|
22
|
-
IntlayerClientProvider: () =>
|
|
21
|
+
IntlayerClientContext: () => import_react_intlayer.IntlayerClientContext,
|
|
22
|
+
IntlayerClientProvider: () => import_IntlayerClientProvider.IntlayerClientProvider,
|
|
23
23
|
getTranslation: () => import_react_intlayer.getTranslation,
|
|
24
24
|
useIntlayer: () => import_react_intlayer.useIntlayer,
|
|
25
25
|
useLocale: () => import_useLocale.useLocale,
|
|
@@ -29,9 +29,10 @@ __export(client_exports, {
|
|
|
29
29
|
module.exports = __toCommonJS(client_exports);
|
|
30
30
|
var import_react_intlayer = require("react-intlayer");
|
|
31
31
|
var import_useLocale = require('./useLocale.cjs');
|
|
32
|
+
var import_IntlayerClientProvider = require('./IntlayerClientProvider.cjs');
|
|
32
33
|
// Annotate the CommonJS export names for ESM import in node:
|
|
33
34
|
0 && (module.exports = {
|
|
34
|
-
|
|
35
|
+
IntlayerClientContext,
|
|
35
36
|
IntlayerClientProvider,
|
|
36
37
|
getTranslation,
|
|
37
38
|
useIntlayer,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/index.ts"],"sourcesContent":["export {\n getTranslation,\n
|
|
1
|
+
{"version":3,"sources":["../../../src/client/index.ts"],"sourcesContent":["export {\n getTranslation,\n IntlayerClientContext,\n useIntlayer,\n useTraduction,\n useLocaleCookie,\n} from 'react-intlayer';\nexport { useLocale } from './useLocale';\nexport {\n IntlayerClientProvider,\n type IntlayerClientProviderProps,\n} from './IntlayerClientProvider';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAMO;AACP,uBAA0B;AAC1B,oCAGO;","names":[]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { IntlayerClientContext, getTranslation, useIntlayer, useLocaleCookie, useTraduction } from 'react-intlayer';
|
|
2
2
|
export { useLocale } from './useLocale.js';
|
|
3
|
+
export { IntlayerClientProvider, IntlayerClientProviderProps } from './IntlayerClientProvider.js';
|
|
3
4
|
import '@intlayer/config/client';
|
|
5
|
+
import 'react';
|
|
@@ -36,8 +36,6 @@ const useLocale = () => {
|
|
|
36
36
|
locale: currentLocale
|
|
37
37
|
} = reactLocaleHook;
|
|
38
38
|
const setLocale = (locale) => {
|
|
39
|
-
if (currentLocale.toString() === locale.toString())
|
|
40
|
-
return;
|
|
41
39
|
if (!availableLocales.includes(locale)) {
|
|
42
40
|
console.error(`Locale ${locale} is not available`);
|
|
43
41
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/useLocale.ts"],"sourcesContent":["import { type Locales, getConfiguration } from '@intlayer/config/client';\nimport { usePathname, useRouter } from 'next/navigation.js';\nimport { useLocaleCookie, useLocaleBase } from 'react-intlayer';\n\nexport const useLocale = () => {\n const { prefixDefault } = getConfiguration().middleware;\n const { setLocaleCookie } = useLocaleCookie();\n const reactLocaleHook = useLocaleBase();\n const router = useRouter();\n const pathname = usePathname();\n\n const {\n defaultLocale,\n availableLocales,\n locale: currentLocale,\n } = reactLocaleHook;\n\n const setLocale = (locale: Locales) => {\n if (
|
|
1
|
+
{"version":3,"sources":["../../../src/client/useLocale.ts"],"sourcesContent":["import { type Locales, getConfiguration } from '@intlayer/config/client';\nimport { usePathname, useRouter } from 'next/navigation.js';\nimport { useLocaleCookie, useLocaleBase } from 'react-intlayer';\n\nexport const useLocale = () => {\n const { prefixDefault } = getConfiguration().middleware;\n const { setLocaleCookie } = useLocaleCookie();\n const reactLocaleHook = useLocaleBase();\n const router = useRouter();\n const pathname = usePathname();\n\n const {\n defaultLocale,\n availableLocales,\n locale: currentLocale,\n } = reactLocaleHook;\n\n const setLocale = (locale: Locales) => {\n if (!availableLocales.includes(locale)) {\n console.error(`Locale ${locale} is not available`);\n return;\n }\n\n setLocaleCookie(locale);\n\n const pathWithoutLocale =\n !prefixDefault && currentLocale.toString() === defaultLocale.toString()\n ? pathname\n : pathname.slice(`/${currentLocale}`.length) || '/';\n\n if (!prefixDefault && locale === defaultLocale) {\n return router.push(pathWithoutLocale);\n }\n\n return router.push(`/${locale}${pathWithoutLocale}`);\n };\n\n return {\n ...reactLocaleHook,\n setLocale,\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA+C;AAC/C,wBAAuC;AACvC,4BAA+C;AAExC,MAAM,YAAY,MAAM;AAC7B,QAAM,EAAE,cAAc,QAAI,gCAAiB,EAAE;AAC7C,QAAM,EAAE,gBAAgB,QAAI,uCAAgB;AAC5C,QAAM,sBAAkB,qCAAc;AACtC,QAAM,aAAS,6BAAU;AACzB,QAAM,eAAW,+BAAY;AAE7B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV,IAAI;AAEJ,QAAM,YAAY,CAAC,WAAoB;AACrC,QAAI,CAAC,iBAAiB,SAAS,MAAM,GAAG;AACtC,cAAQ,MAAM,UAAU,MAAM,mBAAmB;AACjD;AAAA,IACF;AAEA,oBAAgB,MAAM;AAEtB,UAAM,oBACJ,CAAC,iBAAiB,cAAc,SAAS,MAAM,cAAc,SAAS,IAClE,WACA,SAAS,MAAM,IAAI,aAAa,GAAG,MAAM,KAAK;AAEpD,QAAI,CAAC,iBAAiB,WAAW,eAAe;AAC9C,aAAO,OAAO,KAAK,iBAAiB;AAAA,IACtC;AAEA,WAAO,OAAO,KAAK,IAAI,MAAM,GAAG,iBAAiB,EAAE;AAAA,EACrD;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -18,22 +18,22 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var src_exports = {};
|
|
20
20
|
__export(src_exports, {
|
|
21
|
-
|
|
22
|
-
IntlayerClientProvider: () =>
|
|
21
|
+
IntlayerClientContext: () => import_react_intlayer.IntlayerClientContext,
|
|
22
|
+
IntlayerClientProvider: () => import_client.IntlayerClientProvider,
|
|
23
23
|
generateStaticParams: () => import_generateStaticParams.generateStaticParams,
|
|
24
24
|
getTranslation: () => import_react_intlayer.getTranslation,
|
|
25
25
|
useIntlayer: () => import_react_intlayer.useIntlayer,
|
|
26
|
-
useLocale: () =>
|
|
26
|
+
useLocale: () => import_client.useLocale,
|
|
27
27
|
useLocaleCookie: () => import_react_intlayer.useLocaleCookie,
|
|
28
28
|
useTraduction: () => import_react_intlayer.useTraduction
|
|
29
29
|
});
|
|
30
30
|
module.exports = __toCommonJS(src_exports);
|
|
31
31
|
var import_react_intlayer = require("react-intlayer");
|
|
32
32
|
var import_generateStaticParams = require('./generateStaticParams.cjs');
|
|
33
|
-
var
|
|
33
|
+
var import_client = require('./client/index.cjs');
|
|
34
34
|
// Annotate the CommonJS export names for ESM import in node:
|
|
35
35
|
0 && (module.exports = {
|
|
36
|
-
|
|
36
|
+
IntlayerClientContext,
|
|
37
37
|
IntlayerClientProvider,
|
|
38
38
|
generateStaticParams,
|
|
39
39
|
getTranslation,
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export {\n getTranslation,\n
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export {\n getTranslation,\n IntlayerClientContext,\n useIntlayer,\n useTraduction,\n useLocaleCookie,\n type IntlayerNode,\n} from 'react-intlayer';\nexport { generateStaticParams } from './generateStaticParams';\nexport type { LocalParams, NextPageIntlayer } from './types/index';\nexport {\n useLocale,\n IntlayerClientProvider,\n type IntlayerClientProviderProps,\n} from './client/index';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAOO;AACP,kCAAqC;AAErC,oBAIO;","names":[]}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { IntlayerClientContext, IntlayerNode, getTranslation, useIntlayer, useLocaleCookie, useTraduction } from 'react-intlayer';
|
|
2
2
|
export { generateStaticParams } from './generateStaticParams.js';
|
|
3
3
|
export { LocalParams, NextPageIntlayer } from './types/NextPage.js';
|
|
4
4
|
export { useLocale } from './client/useLocale.js';
|
|
5
|
+
export { IntlayerClientProvider, IntlayerClientProviderProps } from './client/IntlayerClientProvider.js';
|
|
5
6
|
import '@intlayer/config/client';
|
|
6
7
|
import 'intlayer';
|
|
7
8
|
import 'next';
|
|
@@ -56,8 +56,7 @@ const intlayerMiddleware = (request) => {
|
|
|
56
56
|
);
|
|
57
57
|
};
|
|
58
58
|
const getCookieLocale = (request) => {
|
|
59
|
-
if (!cookieName)
|
|
60
|
-
return void 0;
|
|
59
|
+
if (!cookieName) return void 0;
|
|
61
60
|
const cookieValue = request.cookies.get(cookieName)?.value;
|
|
62
61
|
if (cookieValue && locales.includes(cookieValue)) {
|
|
63
62
|
return cookieValue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/middleware/intlayerMiddleware.ts"],"sourcesContent":["import { type Locales, getConfiguration } from '@intlayer/config/client';\nimport { type NextRequest, NextResponse } from 'next/server';\nimport { localeDetector } from './localeDetector';\n\nconst { internationalization, middleware } = getConfiguration();\nconst { locales, defaultLocale } = internationalization;\nconst {\n headerName,\n cookieName,\n prefixDefault,\n basePath,\n serverSetCookie,\n noPrefix,\n} = middleware;\n\n/**\n * Middleware that handles the internationalization layer\n *\n * Usage:\n *\n * // ./src/middleware.ts\n *\n * ```ts\n * export { intlayerMiddleware as middleware } from '@intlayer/next/middleware';\n *\n * // applies this middleware only to files in the app directory\n * export const config = {\n * matcher: '/((?!api|static|.*\\\\..*|_next).*)',\n * };\n * ```\n *\n */\nexport const intlayerMiddleware = (request: NextRequest): NextResponse => {\n const pathname = request.nextUrl.pathname;\n const cookieLocale = getCookieLocale(request);\n const basePathTrailingSlash = basePath.endsWith('/');\n\n if (noPrefix) {\n return handleNoPrefix(\n request,\n cookieLocale,\n pathname,\n basePathTrailingSlash\n );\n }\n\n const pathLocale = getPathLocale(pathname);\n return handlePrefix(\n request,\n cookieLocale,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst getCookieLocale = (request: NextRequest): Locales | undefined => {\n if (!cookieName) return undefined;\n const cookieValue = request.cookies.get(cookieName)?.value as Locales;\n if (cookieValue && locales.includes(cookieValue)) {\n return cookieValue;\n }\n};\n\nconst handleNoPrefix = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n const locale = cookieLocale ?? defaultLocale;\n const newPath = constructPath(\n locale,\n pathname,\n basePath,\n basePathTrailingSlash\n );\n return rewriteUrl(request, newPath, locale);\n};\n\nconst getPathLocale = (pathname: string): Locales | undefined =>\n locales.find(\n (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`\n );\n\nconst handlePrefix = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (!pathLocale) {\n return handleMissingPathLocale(\n request,\n cookieLocale,\n pathname,\n basePathTrailingSlash\n );\n }\n return handleExistingPathLocale(\n request,\n cookieLocale,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst handleMissingPathLocale = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n let locale = cookieLocale ?? localeDetector?.(request) ?? defaultLocale;\n if (!locales.includes(locale)) {\n console.warn(\n 'The localeDetector callback must return a locale included in your locales array. Reverting to using defaultLocale.'\n );\n locale = defaultLocale;\n }\n const newPath = constructPath(\n locale,\n pathname,\n basePath,\n basePathTrailingSlash\n );\n return prefixDefault || locale !== defaultLocale\n ? redirectUrl(request, newPath)\n : rewriteUrl(request, newPath, locale);\n};\n\nconst handleExistingPathLocale = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathLocale: Locales,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (\n cookieLocale &&\n cookieLocale !== pathLocale &&\n serverSetCookie !== 'always'\n ) {\n const newPath = handleCookieLocaleMismatch(\n request,\n pathname,\n pathLocale,\n cookieLocale,\n basePath,\n basePathTrailingSlash\n );\n return redirectUrl(request, newPath);\n }\n\n return handleDefaultLocaleRedirect(\n request,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst handleCookieLocaleMismatch = (\n request: NextRequest,\n\n pathname: string,\n pathLocale: Locales,\n cookieLocale: Locales,\n basePath: string,\n basePathTrailingSlash: boolean\n): string => {\n const newPath = pathname.replace(`/${pathLocale}`, `/${cookieLocale}`);\n return constructPath(\n cookieLocale,\n newPath,\n basePath,\n basePathTrailingSlash,\n request.nextUrl.search\n );\n};\n\nconst handleDefaultLocaleRedirect = (\n request: NextRequest,\n pathLocale: Locales,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (!prefixDefault && pathLocale === defaultLocale) {\n let pathWithoutLocale = pathname.slice(`/${pathLocale}`.length) || '/';\n\n if (basePathTrailingSlash) {\n pathWithoutLocale = pathWithoutLocale.slice(1);\n }\n\n if (request.nextUrl.search) {\n pathWithoutLocale += request.nextUrl.search;\n }\n\n return rewriteUrl(request, `${basePath}${pathWithoutLocale}`, pathLocale);\n }\n return rewriteUrl(request, pathname, pathLocale);\n};\n\nconst constructPath = (\n locale: Locales,\n path: string,\n basePath: string,\n basePathTrailingSlash: boolean,\n search?: string\n): string => {\n let newPath = `${locale}${path}`;\n newPath = `${basePath}${basePathTrailingSlash ? '' : '/'}${newPath}`;\n if (search) {\n newPath += search;\n }\n return newPath;\n};\n\nconst rewriteUrl = (\n request: NextRequest,\n newPath: string,\n locale: Locales\n): NextResponse => {\n const response = NextResponse.rewrite(new URL(newPath, request.url));\n response.headers.set(headerName, locale);\n return response;\n};\n\nconst redirectUrl = (request: NextRequest, newPath: string): NextResponse =>\n NextResponse.redirect(new URL(newPath, request.url));\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA+C;AAC/C,oBAA+C;AAC/C,4BAA+B;AAE/B,MAAM,EAAE,sBAAsB,WAAW,QAAI,gCAAiB;AAC9D,MAAM,EAAE,SAAS,cAAc,IAAI;AACnC,MAAM;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,IAAI;AAmBG,MAAM,qBAAqB,CAAC,YAAuC;AACxE,QAAM,WAAW,QAAQ,QAAQ;AACjC,QAAM,eAAe,gBAAgB,OAAO;AAC5C,QAAM,wBAAwB,SAAS,SAAS,GAAG;AAEnD,MAAI,UAAU;AACZ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,cAAc,QAAQ;AACzC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,MAAM,kBAAkB,CAAC,YAA8C;AACrE,MAAI,CAAC
|
|
1
|
+
{"version":3,"sources":["../../../src/middleware/intlayerMiddleware.ts"],"sourcesContent":["import { type Locales, getConfiguration } from '@intlayer/config/client';\nimport { type NextRequest, NextResponse } from 'next/server';\nimport { localeDetector } from './localeDetector';\n\nconst { internationalization, middleware } = getConfiguration();\nconst { locales, defaultLocale } = internationalization;\nconst {\n headerName,\n cookieName,\n prefixDefault,\n basePath,\n serverSetCookie,\n noPrefix,\n} = middleware;\n\n/**\n * Middleware that handles the internationalization layer\n *\n * Usage:\n *\n * // ./src/middleware.ts\n *\n * ```ts\n * export { intlayerMiddleware as middleware } from '@intlayer/next/middleware';\n *\n * // applies this middleware only to files in the app directory\n * export const config = {\n * matcher: '/((?!api|static|.*\\\\..*|_next).*)',\n * };\n * ```\n *\n */\nexport const intlayerMiddleware = (request: NextRequest): NextResponse => {\n const pathname = request.nextUrl.pathname;\n const cookieLocale = getCookieLocale(request);\n const basePathTrailingSlash = basePath.endsWith('/');\n\n if (noPrefix) {\n return handleNoPrefix(\n request,\n cookieLocale,\n pathname,\n basePathTrailingSlash\n );\n }\n\n const pathLocale = getPathLocale(pathname);\n return handlePrefix(\n request,\n cookieLocale,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst getCookieLocale = (request: NextRequest): Locales | undefined => {\n if (!cookieName) return undefined;\n const cookieValue = request.cookies.get(cookieName)?.value as Locales;\n if (cookieValue && locales.includes(cookieValue)) {\n return cookieValue;\n }\n};\n\nconst handleNoPrefix = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n const locale = cookieLocale ?? defaultLocale;\n const newPath = constructPath(\n locale,\n pathname,\n basePath,\n basePathTrailingSlash\n );\n return rewriteUrl(request, newPath, locale);\n};\n\nconst getPathLocale = (pathname: string): Locales | undefined =>\n locales.find(\n (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`\n );\n\nconst handlePrefix = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (!pathLocale) {\n return handleMissingPathLocale(\n request,\n cookieLocale,\n pathname,\n basePathTrailingSlash\n );\n }\n return handleExistingPathLocale(\n request,\n cookieLocale,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst handleMissingPathLocale = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n let locale = cookieLocale ?? localeDetector?.(request) ?? defaultLocale;\n if (!locales.includes(locale)) {\n console.warn(\n 'The localeDetector callback must return a locale included in your locales array. Reverting to using defaultLocale.'\n );\n locale = defaultLocale;\n }\n const newPath = constructPath(\n locale,\n pathname,\n basePath,\n basePathTrailingSlash\n );\n return prefixDefault || locale !== defaultLocale\n ? redirectUrl(request, newPath)\n : rewriteUrl(request, newPath, locale);\n};\n\nconst handleExistingPathLocale = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathLocale: Locales,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (\n cookieLocale &&\n cookieLocale !== pathLocale &&\n serverSetCookie !== 'always'\n ) {\n const newPath = handleCookieLocaleMismatch(\n request,\n pathname,\n pathLocale,\n cookieLocale,\n basePath,\n basePathTrailingSlash\n );\n return redirectUrl(request, newPath);\n }\n\n return handleDefaultLocaleRedirect(\n request,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst handleCookieLocaleMismatch = (\n request: NextRequest,\n\n pathname: string,\n pathLocale: Locales,\n cookieLocale: Locales,\n basePath: string,\n basePathTrailingSlash: boolean\n): string => {\n const newPath = pathname.replace(`/${pathLocale}`, `/${cookieLocale}`);\n return constructPath(\n cookieLocale,\n newPath,\n basePath,\n basePathTrailingSlash,\n request.nextUrl.search\n );\n};\n\nconst handleDefaultLocaleRedirect = (\n request: NextRequest,\n pathLocale: Locales,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (!prefixDefault && pathLocale === defaultLocale) {\n let pathWithoutLocale = pathname.slice(`/${pathLocale}`.length) || '/';\n\n if (basePathTrailingSlash) {\n pathWithoutLocale = pathWithoutLocale.slice(1);\n }\n\n if (request.nextUrl.search) {\n pathWithoutLocale += request.nextUrl.search;\n }\n\n return rewriteUrl(request, `${basePath}${pathWithoutLocale}`, pathLocale);\n }\n return rewriteUrl(request, pathname, pathLocale);\n};\n\nconst constructPath = (\n locale: Locales,\n path: string,\n basePath: string,\n basePathTrailingSlash: boolean,\n search?: string\n): string => {\n let newPath = `${locale}${path}`;\n newPath = `${basePath}${basePathTrailingSlash ? '' : '/'}${newPath}`;\n if (search) {\n newPath += search;\n }\n return newPath;\n};\n\nconst rewriteUrl = (\n request: NextRequest,\n newPath: string,\n locale: Locales\n): NextResponse => {\n const response = NextResponse.rewrite(new URL(newPath, request.url));\n response.headers.set(headerName, locale);\n return response;\n};\n\nconst redirectUrl = (request: NextRequest, newPath: string): NextResponse =>\n NextResponse.redirect(new URL(newPath, request.url));\n"],"mappings":"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","names":["basePath"]}
|
|
@@ -24,9 +24,8 @@ module.exports = __toCommonJS(withIntlayer_exports);
|
|
|
24
24
|
var import_path = require("path");
|
|
25
25
|
var import_config = require("@intlayer/config");
|
|
26
26
|
var import_webpack = require("@intlayer/webpack");
|
|
27
|
-
const withIntlayer = (
|
|
28
|
-
if (typeof nextConfig !== "object")
|
|
29
|
-
nextConfig = {};
|
|
27
|
+
const withIntlayer = (nextConfig = {}) => {
|
|
28
|
+
if (typeof nextConfig !== "object") nextConfig = {};
|
|
30
29
|
const intlayerConfig = (0, import_config.getConfiguration)();
|
|
31
30
|
const env = (0, import_config.formatEnvVariable)("next");
|
|
32
31
|
const { mainDir, baseDir } = intlayerConfig.content;
|
|
@@ -51,7 +50,10 @@ const withIntlayer = (_pluginOptions = {}) => (nextConfig = {}) => {
|
|
|
51
50
|
}
|
|
52
51
|
}
|
|
53
52
|
},
|
|
54
|
-
webpack: (config,
|
|
53
|
+
webpack: (config, options) => {
|
|
54
|
+
if (nextConfig.webpack) {
|
|
55
|
+
config = nextConfig.webpack(config, options);
|
|
56
|
+
}
|
|
55
57
|
config.resolve.alias["@intlayer/dictionaries-entry"] = (0, import_path.resolve)(
|
|
56
58
|
relativeDictionariesPath
|
|
57
59
|
);
|
|
@@ -64,6 +66,7 @@ const withIntlayer = (_pluginOptions = {}) => (nextConfig = {}) => {
|
|
|
64
66
|
test: /\.node$/,
|
|
65
67
|
loader: "node-loader"
|
|
66
68
|
});
|
|
69
|
+
const { isServer, nextRuntime } = options;
|
|
67
70
|
if (isServer && nextRuntime === "nodejs") {
|
|
68
71
|
config.plugins.push(new import_webpack.IntLayerPlugin());
|
|
69
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/withIntlayer.ts"],"sourcesContent":["import { resolve, relative, join } from 'path';\nimport { getConfiguration, formatEnvVariable } from '@intlayer/config';\nimport { IntLayerPlugin } from '@intlayer/webpack';\nimport type { NextConfig } from 'next';\nimport type { NextJsWebpackConfig } from 'next/dist/server/config-shared';\n\ntype
|
|
1
|
+
{"version":3,"sources":["../../../src/server/withIntlayer.ts"],"sourcesContent":["import { resolve, relative, join } from 'path';\nimport { getConfiguration, formatEnvVariable } from '@intlayer/config';\nimport { IntLayerPlugin } from '@intlayer/webpack';\nimport type { NextConfig } from 'next';\nimport type { NextJsWebpackConfig } from 'next/dist/server/config-shared';\n\ntype WebpackParams = Parameters<NextJsWebpackConfig>;\n\n/**\n * A Next.js plugin that adds the intlayer configuration to the webpack configuration\n * and sets the environment variables\n *\n * Usage:\n *\n * ```ts\n * // next.config.js\n * export default withIntlayer(nextConfig)\n * ```\n *\n */\nexport const withIntlayer = (\n nextConfig: Partial<NextConfig> = {}\n): Partial<NextConfig> => {\n if (typeof nextConfig !== 'object') nextConfig = {};\n\n const intlayerConfig = getConfiguration();\n\n // Set all configuration values as environment variables\n const env = formatEnvVariable('next');\n\n const { mainDir, baseDir } = intlayerConfig.content;\n const dictionariesPath = join(mainDir, 'dictionaries.mjs');\n const relativeDictionariesPath = relative(baseDir, dictionariesPath);\n\n return Object.assign({}, nextConfig, {\n env: { ...nextConfig.env, ...env },\n\n experimental: {\n ...(nextConfig.experimental ?? {}),\n // Using Intlayer with Turbopack is not supported as long external modules can't be resolved (such as esbuild or fs)\n turbo: {\n ...(nextConfig.experimental?.turbo ?? {}),\n resolveAlias: {\n ...nextConfig.experimental?.turbo?.resolveAlias,\n '@intlayer/dictionaries-entry': resolve(relativeDictionariesPath),\n },\n\n rules: {\n '*.node': {\n as: '*.node',\n loaders: ['node-loader'],\n },\n },\n },\n },\n\n webpack: (config: WebpackParams['0'], options: WebpackParams[1]) => {\n if (nextConfig.webpack) {\n // Invoke the existing webpack config if it exists\n config = nextConfig.webpack(config, options);\n }\n\n config.resolve.alias['@intlayer/dictionaries-entry'] = resolve(\n relativeDictionariesPath\n );\n\n config.externals.push({\n esbuild: 'esbuild',\n module: 'module',\n fs: 'fs',\n });\n config.module.rules.push({\n test: /\\.node$/,\n loader: 'node-loader',\n });\n\n const { isServer, nextRuntime } = options;\n\n // Apply IntLayerPlugin only on the server-side\n if (isServer && nextRuntime === 'nodejs') {\n config.plugins.push(new IntLayerPlugin());\n }\n\n return config;\n },\n } satisfies Partial<NextConfig>);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwC;AACxC,oBAAoD;AACpD,qBAA+B;AAkBxB,MAAM,eAAe,CAC1B,aAAkC,CAAC,MACX;AACxB,MAAI,OAAO,eAAe,SAAU,cAAa,CAAC;AAElD,QAAM,qBAAiB,gCAAiB;AAGxC,QAAM,UAAM,iCAAkB,MAAM;AAEpC,QAAM,EAAE,SAAS,QAAQ,IAAI,eAAe;AAC5C,QAAM,uBAAmB,kBAAK,SAAS,kBAAkB;AACzD,QAAM,+BAA2B,sBAAS,SAAS,gBAAgB;AAEnE,SAAO,OAAO,OAAO,CAAC,GAAG,YAAY;AAAA,IACnC,KAAK,EAAE,GAAG,WAAW,KAAK,GAAG,IAAI;AAAA,IAEjC,cAAc;AAAA,MACZ,GAAI,WAAW,gBAAgB,CAAC;AAAA;AAAA,MAEhC,OAAO;AAAA,QACL,GAAI,WAAW,cAAc,SAAS,CAAC;AAAA,QACvC,cAAc;AAAA,UACZ,GAAG,WAAW,cAAc,OAAO;AAAA,UACnC,oCAAgC,qBAAQ,wBAAwB;AAAA,QAClE;AAAA,QAEA,OAAO;AAAA,UACL,UAAU;AAAA,YACR,IAAI;AAAA,YACJ,SAAS,CAAC,aAAa;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,SAAS,CAAC,QAA4B,YAA8B;AAClE,UAAI,WAAW,SAAS;AAEtB,iBAAS,WAAW,QAAQ,QAAQ,OAAO;AAAA,MAC7C;AAEA,aAAO,QAAQ,MAAM,8BAA8B,QAAI;AAAA,QACrD;AAAA,MACF;AAEA,aAAO,UAAU,KAAK;AAAA,QACpB,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,IAAI;AAAA,MACN,CAAC;AACD,aAAO,OAAO,MAAM,KAAK;AAAA,QACvB,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAC;AAED,YAAM,EAAE,UAAU,YAAY,IAAI;AAGlC,UAAI,YAAY,gBAAgB,UAAU;AACxC,eAAO,QAAQ,KAAK,IAAI,8BAAe,CAAC;AAAA,MAC1C;AAEA,aAAO;AAAA,IACT;AAAA,EACF,CAA+B;AACjC;","names":[]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import 'react-intlayer/server';
|
|
2
2
|
import { NextConfig } from 'next';
|
|
3
3
|
|
|
4
|
-
type PluginOptions = {};
|
|
5
4
|
/**
|
|
6
5
|
* A Next.js plugin that adds the intlayer configuration to the webpack configuration
|
|
7
6
|
* and sets the environment variables
|
|
@@ -14,6 +13,6 @@ type PluginOptions = {};
|
|
|
14
13
|
* ```
|
|
15
14
|
*
|
|
16
15
|
*/
|
|
17
|
-
declare const withIntlayer: (
|
|
16
|
+
declare const withIntlayer: (nextConfig?: Partial<NextConfig>) => Partial<NextConfig>;
|
|
18
17
|
|
|
19
18
|
export { withIntlayer };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { IntlayerProviderProps } from 'react-intlayer';
|
|
3
|
+
|
|
4
|
+
type IntlayerClientProviderProps = IntlayerProviderProps;
|
|
5
|
+
declare const IntlayerClientProvider: FC<IntlayerProviderProps>;
|
|
6
|
+
|
|
7
|
+
export { IntlayerClientProvider, type IntlayerClientProviderProps };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { IntlayerProvider } from "react-intlayer";
|
|
4
|
+
import { useLocale } from './useLocale.mjs';
|
|
5
|
+
const IntlayerClientProvider = (props) => {
|
|
6
|
+
const { setLocale } = useLocale();
|
|
7
|
+
return /* @__PURE__ */ jsx(IntlayerProvider, { setLocale, ...props });
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
IntlayerClientProvider
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=IntlayerClientProvider.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/client/IntlayerClientProvider.tsx"],"sourcesContent":["'use client';\n\nimport type { FC } from 'react';\nimport { IntlayerProvider, type IntlayerProviderProps } from 'react-intlayer';\nimport { useLocale } from './useLocale';\n\nexport type IntlayerClientProviderProps = IntlayerProviderProps;\n\nexport const IntlayerClientProvider: FC<IntlayerProviderProps> = (props) => {\n const { setLocale } = useLocale();\n return <IntlayerProvider setLocale={setLocale} {...props} />;\n};\n"],"mappings":";AAUS;AAPT,SAAS,wBAAoD;AAC7D,SAAS,iBAAiB;AAInB,MAAM,yBAAoD,CAAC,UAAU;AAC1E,QAAM,EAAE,UAAU,IAAI,UAAU;AAChC,SAAO,oBAAC,oBAAiB,WAAuB,GAAG,OAAO;AAC5D;","names":[]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { IntlayerClientContext, getTranslation, useIntlayer, useLocaleCookie, useTraduction } from 'react-intlayer';
|
|
2
2
|
export { useLocale } from './useLocale.mjs';
|
|
3
|
+
export { IntlayerClientProvider, IntlayerClientProviderProps } from './IntlayerClientProvider.mjs';
|
|
3
4
|
import '@intlayer/config/client';
|
|
5
|
+
import 'react';
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getTranslation,
|
|
3
|
-
|
|
4
|
-
IntlayerClient,
|
|
3
|
+
IntlayerClientContext,
|
|
5
4
|
useIntlayer,
|
|
6
5
|
useTraduction,
|
|
7
6
|
useLocaleCookie
|
|
8
7
|
} from "react-intlayer";
|
|
9
8
|
import { useLocale } from './useLocale.mjs';
|
|
9
|
+
import {
|
|
10
|
+
IntlayerClientProvider
|
|
11
|
+
} from './IntlayerClientProvider.mjs';
|
|
10
12
|
export {
|
|
11
|
-
|
|
13
|
+
IntlayerClientContext,
|
|
12
14
|
IntlayerClientProvider,
|
|
13
15
|
getTranslation,
|
|
14
16
|
useIntlayer,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/index.ts"],"sourcesContent":["export {\n getTranslation,\n
|
|
1
|
+
{"version":3,"sources":["../../../src/client/index.ts"],"sourcesContent":["export {\n getTranslation,\n IntlayerClientContext,\n useIntlayer,\n useTraduction,\n useLocaleCookie,\n} from 'react-intlayer';\nexport { useLocale } from './useLocale';\nexport {\n IntlayerClientProvider,\n type IntlayerClientProviderProps,\n} from './IntlayerClientProvider';\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,OAEK;","names":[]}
|
|
@@ -13,8 +13,6 @@ const useLocale = () => {
|
|
|
13
13
|
locale: currentLocale
|
|
14
14
|
} = reactLocaleHook;
|
|
15
15
|
const setLocale = (locale) => {
|
|
16
|
-
if (currentLocale.toString() === locale.toString())
|
|
17
|
-
return;
|
|
18
16
|
if (!availableLocales.includes(locale)) {
|
|
19
17
|
console.error(`Locale ${locale} is not available`);
|
|
20
18
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/useLocale.ts"],"sourcesContent":["import { type Locales, getConfiguration } from '@intlayer/config/client';\nimport { usePathname, useRouter } from 'next/navigation.js';\nimport { useLocaleCookie, useLocaleBase } from 'react-intlayer';\n\nexport const useLocale = () => {\n const { prefixDefault } = getConfiguration().middleware;\n const { setLocaleCookie } = useLocaleCookie();\n const reactLocaleHook = useLocaleBase();\n const router = useRouter();\n const pathname = usePathname();\n\n const {\n defaultLocale,\n availableLocales,\n locale: currentLocale,\n } = reactLocaleHook;\n\n const setLocale = (locale: Locales) => {\n if (
|
|
1
|
+
{"version":3,"sources":["../../../src/client/useLocale.ts"],"sourcesContent":["import { type Locales, getConfiguration } from '@intlayer/config/client';\nimport { usePathname, useRouter } from 'next/navigation.js';\nimport { useLocaleCookie, useLocaleBase } from 'react-intlayer';\n\nexport const useLocale = () => {\n const { prefixDefault } = getConfiguration().middleware;\n const { setLocaleCookie } = useLocaleCookie();\n const reactLocaleHook = useLocaleBase();\n const router = useRouter();\n const pathname = usePathname();\n\n const {\n defaultLocale,\n availableLocales,\n locale: currentLocale,\n } = reactLocaleHook;\n\n const setLocale = (locale: Locales) => {\n if (!availableLocales.includes(locale)) {\n console.error(`Locale ${locale} is not available`);\n return;\n }\n\n setLocaleCookie(locale);\n\n const pathWithoutLocale =\n !prefixDefault && currentLocale.toString() === defaultLocale.toString()\n ? pathname\n : pathname.slice(`/${currentLocale}`.length) || '/';\n\n if (!prefixDefault && locale === defaultLocale) {\n return router.push(pathWithoutLocale);\n }\n\n return router.push(`/${locale}${pathWithoutLocale}`);\n };\n\n return {\n ...reactLocaleHook,\n setLocale,\n };\n};\n"],"mappings":"AAAA,SAAuB,wBAAwB;AAC/C,SAAS,aAAa,iBAAiB;AACvC,SAAS,iBAAiB,qBAAqB;AAExC,MAAM,YAAY,MAAM;AAC7B,QAAM,EAAE,cAAc,IAAI,iBAAiB,EAAE;AAC7C,QAAM,EAAE,gBAAgB,IAAI,gBAAgB;AAC5C,QAAM,kBAAkB,cAAc;AACtC,QAAM,SAAS,UAAU;AACzB,QAAM,WAAW,YAAY;AAE7B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV,IAAI;AAEJ,QAAM,YAAY,CAAC,WAAoB;AACrC,QAAI,CAAC,iBAAiB,SAAS,MAAM,GAAG;AACtC,cAAQ,MAAM,UAAU,MAAM,mBAAmB;AACjD;AAAA,IACF;AAEA,oBAAgB,MAAM;AAEtB,UAAM,oBACJ,CAAC,iBAAiB,cAAc,SAAS,MAAM,cAAc,SAAS,IAClE,WACA,SAAS,MAAM,IAAI,aAAa,GAAG,MAAM,KAAK;AAEpD,QAAI,CAAC,iBAAiB,WAAW,eAAe;AAC9C,aAAO,OAAO,KAAK,iBAAiB;AAAA,IACtC;AAEA,WAAO,OAAO,KAAK,IAAI,MAAM,GAAG,iBAAiB,EAAE;AAAA,EACrD;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
|
package/dist/esm/index.d.mts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { IntlayerClientContext, IntlayerNode, getTranslation, useIntlayer, useLocaleCookie, useTraduction } from 'react-intlayer';
|
|
2
2
|
export { generateStaticParams } from './generateStaticParams.mjs';
|
|
3
3
|
export { LocalParams, NextPageIntlayer } from './types/NextPage.mjs';
|
|
4
4
|
export { useLocale } from './client/useLocale.mjs';
|
|
5
|
+
export { IntlayerClientProvider, IntlayerClientProviderProps } from './client/IntlayerClientProvider.mjs';
|
|
5
6
|
import '@intlayer/config/client';
|
|
6
7
|
import 'intlayer';
|
|
7
8
|
import 'next';
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getTranslation,
|
|
3
|
-
|
|
4
|
-
IntlayerClient,
|
|
3
|
+
IntlayerClientContext,
|
|
5
4
|
useIntlayer,
|
|
6
5
|
useTraduction,
|
|
7
6
|
useLocaleCookie
|
|
8
7
|
} from "react-intlayer";
|
|
9
8
|
import { generateStaticParams } from './generateStaticParams.mjs';
|
|
10
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
useLocale,
|
|
11
|
+
IntlayerClientProvider
|
|
12
|
+
} from './client/index.mjs';
|
|
11
13
|
export {
|
|
12
|
-
|
|
14
|
+
IntlayerClientContext,
|
|
13
15
|
IntlayerClientProvider,
|
|
14
16
|
generateStaticParams,
|
|
15
17
|
getTranslation,
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export {\n getTranslation,\n
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export {\n getTranslation,\n IntlayerClientContext,\n useIntlayer,\n useTraduction,\n useLocaleCookie,\n type IntlayerNode,\n} from 'react-intlayer';\nexport { generateStaticParams } from './generateStaticParams';\nexport type { LocalParams, NextPageIntlayer } from './types/index';\nexport {\n useLocale,\n IntlayerClientProvider,\n type IntlayerClientProviderProps,\n} from './client/index';\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,4BAA4B;AAErC;AAAA,EACE;AAAA,EACA;AAAA,OAEK;","names":[]}
|
|
@@ -33,8 +33,7 @@ const intlayerMiddleware = (request) => {
|
|
|
33
33
|
);
|
|
34
34
|
};
|
|
35
35
|
const getCookieLocale = (request) => {
|
|
36
|
-
if (!cookieName)
|
|
37
|
-
return void 0;
|
|
36
|
+
if (!cookieName) return void 0;
|
|
38
37
|
const cookieValue = request.cookies.get(cookieName)?.value;
|
|
39
38
|
if (cookieValue && locales.includes(cookieValue)) {
|
|
40
39
|
return cookieValue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/middleware/intlayerMiddleware.ts"],"sourcesContent":["import { type Locales, getConfiguration } from '@intlayer/config/client';\nimport { type NextRequest, NextResponse } from 'next/server';\nimport { localeDetector } from './localeDetector';\n\nconst { internationalization, middleware } = getConfiguration();\nconst { locales, defaultLocale } = internationalization;\nconst {\n headerName,\n cookieName,\n prefixDefault,\n basePath,\n serverSetCookie,\n noPrefix,\n} = middleware;\n\n/**\n * Middleware that handles the internationalization layer\n *\n * Usage:\n *\n * // ./src/middleware.ts\n *\n * ```ts\n * export { intlayerMiddleware as middleware } from '@intlayer/next/middleware';\n *\n * // applies this middleware only to files in the app directory\n * export const config = {\n * matcher: '/((?!api|static|.*\\\\..*|_next).*)',\n * };\n * ```\n *\n */\nexport const intlayerMiddleware = (request: NextRequest): NextResponse => {\n const pathname = request.nextUrl.pathname;\n const cookieLocale = getCookieLocale(request);\n const basePathTrailingSlash = basePath.endsWith('/');\n\n if (noPrefix) {\n return handleNoPrefix(\n request,\n cookieLocale,\n pathname,\n basePathTrailingSlash\n );\n }\n\n const pathLocale = getPathLocale(pathname);\n return handlePrefix(\n request,\n cookieLocale,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst getCookieLocale = (request: NextRequest): Locales | undefined => {\n if (!cookieName) return undefined;\n const cookieValue = request.cookies.get(cookieName)?.value as Locales;\n if (cookieValue && locales.includes(cookieValue)) {\n return cookieValue;\n }\n};\n\nconst handleNoPrefix = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n const locale = cookieLocale ?? defaultLocale;\n const newPath = constructPath(\n locale,\n pathname,\n basePath,\n basePathTrailingSlash\n );\n return rewriteUrl(request, newPath, locale);\n};\n\nconst getPathLocale = (pathname: string): Locales | undefined =>\n locales.find(\n (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`\n );\n\nconst handlePrefix = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (!pathLocale) {\n return handleMissingPathLocale(\n request,\n cookieLocale,\n pathname,\n basePathTrailingSlash\n );\n }\n return handleExistingPathLocale(\n request,\n cookieLocale,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst handleMissingPathLocale = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n let locale = cookieLocale ?? localeDetector?.(request) ?? defaultLocale;\n if (!locales.includes(locale)) {\n console.warn(\n 'The localeDetector callback must return a locale included in your locales array. Reverting to using defaultLocale.'\n );\n locale = defaultLocale;\n }\n const newPath = constructPath(\n locale,\n pathname,\n basePath,\n basePathTrailingSlash\n );\n return prefixDefault || locale !== defaultLocale\n ? redirectUrl(request, newPath)\n : rewriteUrl(request, newPath, locale);\n};\n\nconst handleExistingPathLocale = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathLocale: Locales,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (\n cookieLocale &&\n cookieLocale !== pathLocale &&\n serverSetCookie !== 'always'\n ) {\n const newPath = handleCookieLocaleMismatch(\n request,\n pathname,\n pathLocale,\n cookieLocale,\n basePath,\n basePathTrailingSlash\n );\n return redirectUrl(request, newPath);\n }\n\n return handleDefaultLocaleRedirect(\n request,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst handleCookieLocaleMismatch = (\n request: NextRequest,\n\n pathname: string,\n pathLocale: Locales,\n cookieLocale: Locales,\n basePath: string,\n basePathTrailingSlash: boolean\n): string => {\n const newPath = pathname.replace(`/${pathLocale}`, `/${cookieLocale}`);\n return constructPath(\n cookieLocale,\n newPath,\n basePath,\n basePathTrailingSlash,\n request.nextUrl.search\n );\n};\n\nconst handleDefaultLocaleRedirect = (\n request: NextRequest,\n pathLocale: Locales,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (!prefixDefault && pathLocale === defaultLocale) {\n let pathWithoutLocale = pathname.slice(`/${pathLocale}`.length) || '/';\n\n if (basePathTrailingSlash) {\n pathWithoutLocale = pathWithoutLocale.slice(1);\n }\n\n if (request.nextUrl.search) {\n pathWithoutLocale += request.nextUrl.search;\n }\n\n return rewriteUrl(request, `${basePath}${pathWithoutLocale}`, pathLocale);\n }\n return rewriteUrl(request, pathname, pathLocale);\n};\n\nconst constructPath = (\n locale: Locales,\n path: string,\n basePath: string,\n basePathTrailingSlash: boolean,\n search?: string\n): string => {\n let newPath = `${locale}${path}`;\n newPath = `${basePath}${basePathTrailingSlash ? '' : '/'}${newPath}`;\n if (search) {\n newPath += search;\n }\n return newPath;\n};\n\nconst rewriteUrl = (\n request: NextRequest,\n newPath: string,\n locale: Locales\n): NextResponse => {\n const response = NextResponse.rewrite(new URL(newPath, request.url));\n response.headers.set(headerName, locale);\n return response;\n};\n\nconst redirectUrl = (request: NextRequest, newPath: string): NextResponse =>\n NextResponse.redirect(new URL(newPath, request.url));\n"],"mappings":"AAAA,SAAuB,wBAAwB;AAC/C,SAA2B,oBAAoB;AAC/C,SAAS,sBAAsB;AAE/B,MAAM,EAAE,sBAAsB,WAAW,IAAI,iBAAiB;AAC9D,MAAM,EAAE,SAAS,cAAc,IAAI;AACnC,MAAM;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,IAAI;AAmBG,MAAM,qBAAqB,CAAC,YAAuC;AACxE,QAAM,WAAW,QAAQ,QAAQ;AACjC,QAAM,eAAe,gBAAgB,OAAO;AAC5C,QAAM,wBAAwB,SAAS,SAAS,GAAG;AAEnD,MAAI,UAAU;AACZ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,cAAc,QAAQ;AACzC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,MAAM,kBAAkB,CAAC,YAA8C;AACrE,MAAI,CAAC
|
|
1
|
+
{"version":3,"sources":["../../../src/middleware/intlayerMiddleware.ts"],"sourcesContent":["import { type Locales, getConfiguration } from '@intlayer/config/client';\nimport { type NextRequest, NextResponse } from 'next/server';\nimport { localeDetector } from './localeDetector';\n\nconst { internationalization, middleware } = getConfiguration();\nconst { locales, defaultLocale } = internationalization;\nconst {\n headerName,\n cookieName,\n prefixDefault,\n basePath,\n serverSetCookie,\n noPrefix,\n} = middleware;\n\n/**\n * Middleware that handles the internationalization layer\n *\n * Usage:\n *\n * // ./src/middleware.ts\n *\n * ```ts\n * export { intlayerMiddleware as middleware } from '@intlayer/next/middleware';\n *\n * // applies this middleware only to files in the app directory\n * export const config = {\n * matcher: '/((?!api|static|.*\\\\..*|_next).*)',\n * };\n * ```\n *\n */\nexport const intlayerMiddleware = (request: NextRequest): NextResponse => {\n const pathname = request.nextUrl.pathname;\n const cookieLocale = getCookieLocale(request);\n const basePathTrailingSlash = basePath.endsWith('/');\n\n if (noPrefix) {\n return handleNoPrefix(\n request,\n cookieLocale,\n pathname,\n basePathTrailingSlash\n );\n }\n\n const pathLocale = getPathLocale(pathname);\n return handlePrefix(\n request,\n cookieLocale,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst getCookieLocale = (request: NextRequest): Locales | undefined => {\n if (!cookieName) return undefined;\n const cookieValue = request.cookies.get(cookieName)?.value as Locales;\n if (cookieValue && locales.includes(cookieValue)) {\n return cookieValue;\n }\n};\n\nconst handleNoPrefix = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n const locale = cookieLocale ?? defaultLocale;\n const newPath = constructPath(\n locale,\n pathname,\n basePath,\n basePathTrailingSlash\n );\n return rewriteUrl(request, newPath, locale);\n};\n\nconst getPathLocale = (pathname: string): Locales | undefined =>\n locales.find(\n (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`\n );\n\nconst handlePrefix = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (!pathLocale) {\n return handleMissingPathLocale(\n request,\n cookieLocale,\n pathname,\n basePathTrailingSlash\n );\n }\n return handleExistingPathLocale(\n request,\n cookieLocale,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst handleMissingPathLocale = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n let locale = cookieLocale ?? localeDetector?.(request) ?? defaultLocale;\n if (!locales.includes(locale)) {\n console.warn(\n 'The localeDetector callback must return a locale included in your locales array. Reverting to using defaultLocale.'\n );\n locale = defaultLocale;\n }\n const newPath = constructPath(\n locale,\n pathname,\n basePath,\n basePathTrailingSlash\n );\n return prefixDefault || locale !== defaultLocale\n ? redirectUrl(request, newPath)\n : rewriteUrl(request, newPath, locale);\n};\n\nconst handleExistingPathLocale = (\n request: NextRequest,\n cookieLocale: Locales | undefined,\n pathLocale: Locales,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (\n cookieLocale &&\n cookieLocale !== pathLocale &&\n serverSetCookie !== 'always'\n ) {\n const newPath = handleCookieLocaleMismatch(\n request,\n pathname,\n pathLocale,\n cookieLocale,\n basePath,\n basePathTrailingSlash\n );\n return redirectUrl(request, newPath);\n }\n\n return handleDefaultLocaleRedirect(\n request,\n pathLocale,\n pathname,\n basePathTrailingSlash\n );\n};\n\nconst handleCookieLocaleMismatch = (\n request: NextRequest,\n\n pathname: string,\n pathLocale: Locales,\n cookieLocale: Locales,\n basePath: string,\n basePathTrailingSlash: boolean\n): string => {\n const newPath = pathname.replace(`/${pathLocale}`, `/${cookieLocale}`);\n return constructPath(\n cookieLocale,\n newPath,\n basePath,\n basePathTrailingSlash,\n request.nextUrl.search\n );\n};\n\nconst handleDefaultLocaleRedirect = (\n request: NextRequest,\n pathLocale: Locales,\n pathname: string,\n basePathTrailingSlash: boolean\n): NextResponse => {\n if (!prefixDefault && pathLocale === defaultLocale) {\n let pathWithoutLocale = pathname.slice(`/${pathLocale}`.length) || '/';\n\n if (basePathTrailingSlash) {\n pathWithoutLocale = pathWithoutLocale.slice(1);\n }\n\n if (request.nextUrl.search) {\n pathWithoutLocale += request.nextUrl.search;\n }\n\n return rewriteUrl(request, `${basePath}${pathWithoutLocale}`, pathLocale);\n }\n return rewriteUrl(request, pathname, pathLocale);\n};\n\nconst constructPath = (\n locale: Locales,\n path: string,\n basePath: string,\n basePathTrailingSlash: boolean,\n search?: string\n): string => {\n let newPath = `${locale}${path}`;\n newPath = `${basePath}${basePathTrailingSlash ? '' : '/'}${newPath}`;\n if (search) {\n newPath += search;\n }\n return newPath;\n};\n\nconst rewriteUrl = (\n request: NextRequest,\n newPath: string,\n locale: Locales\n): NextResponse => {\n const response = NextResponse.rewrite(new URL(newPath, request.url));\n response.headers.set(headerName, locale);\n return response;\n};\n\nconst redirectUrl = (request: NextRequest, newPath: string): NextResponse =>\n NextResponse.redirect(new URL(newPath, request.url));\n"],"mappings":"AAAA,SAAuB,wBAAwB;AAC/C,SAA2B,oBAAoB;AAC/C,SAAS,sBAAsB;AAE/B,MAAM,EAAE,sBAAsB,WAAW,IAAI,iBAAiB;AAC9D,MAAM,EAAE,SAAS,cAAc,IAAI;AACnC,MAAM;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,IAAI;AAmBG,MAAM,qBAAqB,CAAC,YAAuC;AACxE,QAAM,WAAW,QAAQ,QAAQ;AACjC,QAAM,eAAe,gBAAgB,OAAO;AAC5C,QAAM,wBAAwB,SAAS,SAAS,GAAG;AAEnD,MAAI,UAAU;AACZ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,cAAc,QAAQ;AACzC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,MAAM,kBAAkB,CAAC,YAA8C;AACrE,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,cAAc,QAAQ,QAAQ,IAAI,UAAU,GAAG;AACrD,MAAI,eAAe,QAAQ,SAAS,WAAW,GAAG;AAChD,WAAO;AAAA,EACT;AACF;AAEA,MAAM,iBAAiB,CACrB,SACA,cACA,UACA,0BACiB;AACjB,QAAM,SAAS,gBAAgB;AAC/B,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,WAAW,SAAS,SAAS,MAAM;AAC5C;AAEA,MAAM,gBAAgB,CAAC,aACrB,QAAQ;AAAA,EACN,CAAC,WAAW,SAAS,WAAW,IAAI,MAAM,GAAG,KAAK,aAAa,IAAI,MAAM;AAC3E;AAEF,MAAM,eAAe,CACnB,SACA,cACA,YACA,UACA,0BACiB;AACjB,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,MAAM,0BAA0B,CAC9B,SACA,cACA,UACA,0BACiB;AACjB,MAAI,SAAS,gBAAgB,iBAAiB,OAAO,KAAK;AAC1D,MAAI,CAAC,QAAQ,SAAS,MAAM,GAAG;AAC7B,YAAQ;AAAA,MACN;AAAA,IACF;AACA,aAAS;AAAA,EACX;AACA,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,iBAAiB,WAAW,gBAC/B,YAAY,SAAS,OAAO,IAC5B,WAAW,SAAS,SAAS,MAAM;AACzC;AAEA,MAAM,2BAA2B,CAC/B,SACA,cACA,YACA,UACA,0BACiB;AACjB,MACE,gBACA,iBAAiB,cACjB,oBAAoB,UACpB;AACA,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO,YAAY,SAAS,OAAO;AAAA,EACrC;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,MAAM,6BAA6B,CACjC,SAEA,UACA,YACA,cACAA,WACA,0BACW;AACX,QAAM,UAAU,SAAS,QAAQ,IAAI,UAAU,IAAI,IAAI,YAAY,EAAE;AACrE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACAA;AAAA,IACA;AAAA,IACA,QAAQ,QAAQ;AAAA,EAClB;AACF;AAEA,MAAM,8BAA8B,CAClC,SACA,YACA,UACA,0BACiB;AACjB,MAAI,CAAC,iBAAiB,eAAe,eAAe;AAClD,QAAI,oBAAoB,SAAS,MAAM,IAAI,UAAU,GAAG,MAAM,KAAK;AAEnE,QAAI,uBAAuB;AACzB,0BAAoB,kBAAkB,MAAM,CAAC;AAAA,IAC/C;AAEA,QAAI,QAAQ,QAAQ,QAAQ;AAC1B,2BAAqB,QAAQ,QAAQ;AAAA,IACvC;AAEA,WAAO,WAAW,SAAS,GAAG,QAAQ,GAAG,iBAAiB,IAAI,UAAU;AAAA,EAC1E;AACA,SAAO,WAAW,SAAS,UAAU,UAAU;AACjD;AAEA,MAAM,gBAAgB,CACpB,QACA,MACAA,WACA,uBACA,WACW;AACX,MAAI,UAAU,GAAG,MAAM,GAAG,IAAI;AAC9B,YAAU,GAAGA,SAAQ,GAAG,wBAAwB,KAAK,GAAG,GAAG,OAAO;AAClE,MAAI,QAAQ;AACV,eAAW;AAAA,EACb;AACA,SAAO;AACT;AAEA,MAAM,aAAa,CACjB,SACA,SACA,WACiB;AACjB,QAAM,WAAW,aAAa,QAAQ,IAAI,IAAI,SAAS,QAAQ,GAAG,CAAC;AACnE,WAAS,QAAQ,IAAI,YAAY,MAAM;AACvC,SAAO;AACT;AAEA,MAAM,cAAc,CAAC,SAAsB,YACzC,aAAa,SAAS,IAAI,IAAI,SAAS,QAAQ,GAAG,CAAC;","names":["basePath"]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import 'react-intlayer/server';
|
|
2
2
|
import { NextConfig } from 'next';
|
|
3
3
|
|
|
4
|
-
type PluginOptions = {};
|
|
5
4
|
/**
|
|
6
5
|
* A Next.js plugin that adds the intlayer configuration to the webpack configuration
|
|
7
6
|
* and sets the environment variables
|
|
@@ -14,6 +13,6 @@ type PluginOptions = {};
|
|
|
14
13
|
* ```
|
|
15
14
|
*
|
|
16
15
|
*/
|
|
17
|
-
declare const withIntlayer: (
|
|
16
|
+
declare const withIntlayer: (nextConfig?: Partial<NextConfig>) => Partial<NextConfig>;
|
|
18
17
|
|
|
19
18
|
export { withIntlayer };
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { resolve, relative, join } from "path";
|
|
2
2
|
import { getConfiguration, formatEnvVariable } from "@intlayer/config";
|
|
3
3
|
import { IntLayerPlugin } from "@intlayer/webpack";
|
|
4
|
-
const withIntlayer = (
|
|
5
|
-
if (typeof nextConfig !== "object")
|
|
6
|
-
nextConfig = {};
|
|
4
|
+
const withIntlayer = (nextConfig = {}) => {
|
|
5
|
+
if (typeof nextConfig !== "object") nextConfig = {};
|
|
7
6
|
const intlayerConfig = getConfiguration();
|
|
8
7
|
const env = formatEnvVariable("next");
|
|
9
8
|
const { mainDir, baseDir } = intlayerConfig.content;
|
|
@@ -28,7 +27,10 @@ const withIntlayer = (_pluginOptions = {}) => (nextConfig = {}) => {
|
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
},
|
|
31
|
-
webpack: (config,
|
|
30
|
+
webpack: (config, options) => {
|
|
31
|
+
if (nextConfig.webpack) {
|
|
32
|
+
config = nextConfig.webpack(config, options);
|
|
33
|
+
}
|
|
32
34
|
config.resolve.alias["@intlayer/dictionaries-entry"] = resolve(
|
|
33
35
|
relativeDictionariesPath
|
|
34
36
|
);
|
|
@@ -41,6 +43,7 @@ const withIntlayer = (_pluginOptions = {}) => (nextConfig = {}) => {
|
|
|
41
43
|
test: /\.node$/,
|
|
42
44
|
loader: "node-loader"
|
|
43
45
|
});
|
|
46
|
+
const { isServer, nextRuntime } = options;
|
|
44
47
|
if (isServer && nextRuntime === "nodejs") {
|
|
45
48
|
config.plugins.push(new IntLayerPlugin());
|
|
46
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/withIntlayer.ts"],"sourcesContent":["import { resolve, relative, join } from 'path';\nimport { getConfiguration, formatEnvVariable } from '@intlayer/config';\nimport { IntLayerPlugin } from '@intlayer/webpack';\nimport type { NextConfig } from 'next';\nimport type { NextJsWebpackConfig } from 'next/dist/server/config-shared';\n\ntype
|
|
1
|
+
{"version":3,"sources":["../../../src/server/withIntlayer.ts"],"sourcesContent":["import { resolve, relative, join } from 'path';\nimport { getConfiguration, formatEnvVariable } from '@intlayer/config';\nimport { IntLayerPlugin } from '@intlayer/webpack';\nimport type { NextConfig } from 'next';\nimport type { NextJsWebpackConfig } from 'next/dist/server/config-shared';\n\ntype WebpackParams = Parameters<NextJsWebpackConfig>;\n\n/**\n * A Next.js plugin that adds the intlayer configuration to the webpack configuration\n * and sets the environment variables\n *\n * Usage:\n *\n * ```ts\n * // next.config.js\n * export default withIntlayer(nextConfig)\n * ```\n *\n */\nexport const withIntlayer = (\n nextConfig: Partial<NextConfig> = {}\n): Partial<NextConfig> => {\n if (typeof nextConfig !== 'object') nextConfig = {};\n\n const intlayerConfig = getConfiguration();\n\n // Set all configuration values as environment variables\n const env = formatEnvVariable('next');\n\n const { mainDir, baseDir } = intlayerConfig.content;\n const dictionariesPath = join(mainDir, 'dictionaries.mjs');\n const relativeDictionariesPath = relative(baseDir, dictionariesPath);\n\n return Object.assign({}, nextConfig, {\n env: { ...nextConfig.env, ...env },\n\n experimental: {\n ...(nextConfig.experimental ?? {}),\n // Using Intlayer with Turbopack is not supported as long external modules can't be resolved (such as esbuild or fs)\n turbo: {\n ...(nextConfig.experimental?.turbo ?? {}),\n resolveAlias: {\n ...nextConfig.experimental?.turbo?.resolveAlias,\n '@intlayer/dictionaries-entry': resolve(relativeDictionariesPath),\n },\n\n rules: {\n '*.node': {\n as: '*.node',\n loaders: ['node-loader'],\n },\n },\n },\n },\n\n webpack: (config: WebpackParams['0'], options: WebpackParams[1]) => {\n if (nextConfig.webpack) {\n // Invoke the existing webpack config if it exists\n config = nextConfig.webpack(config, options);\n }\n\n config.resolve.alias['@intlayer/dictionaries-entry'] = resolve(\n relativeDictionariesPath\n );\n\n config.externals.push({\n esbuild: 'esbuild',\n module: 'module',\n fs: 'fs',\n });\n config.module.rules.push({\n test: /\\.node$/,\n loader: 'node-loader',\n });\n\n const { isServer, nextRuntime } = options;\n\n // Apply IntLayerPlugin only on the server-side\n if (isServer && nextRuntime === 'nodejs') {\n config.plugins.push(new IntLayerPlugin());\n }\n\n return config;\n },\n } satisfies Partial<NextConfig>);\n};\n"],"mappings":"AAAA,SAAS,SAAS,UAAU,YAAY;AACxC,SAAS,kBAAkB,yBAAyB;AACpD,SAAS,sBAAsB;AAkBxB,MAAM,eAAe,CAC1B,aAAkC,CAAC,MACX;AACxB,MAAI,OAAO,eAAe,SAAU,cAAa,CAAC;AAElD,QAAM,iBAAiB,iBAAiB;AAGxC,QAAM,MAAM,kBAAkB,MAAM;AAEpC,QAAM,EAAE,SAAS,QAAQ,IAAI,eAAe;AAC5C,QAAM,mBAAmB,KAAK,SAAS,kBAAkB;AACzD,QAAM,2BAA2B,SAAS,SAAS,gBAAgB;AAEnE,SAAO,OAAO,OAAO,CAAC,GAAG,YAAY;AAAA,IACnC,KAAK,EAAE,GAAG,WAAW,KAAK,GAAG,IAAI;AAAA,IAEjC,cAAc;AAAA,MACZ,GAAI,WAAW,gBAAgB,CAAC;AAAA;AAAA,MAEhC,OAAO;AAAA,QACL,GAAI,WAAW,cAAc,SAAS,CAAC;AAAA,QACvC,cAAc;AAAA,UACZ,GAAG,WAAW,cAAc,OAAO;AAAA,UACnC,gCAAgC,QAAQ,wBAAwB;AAAA,QAClE;AAAA,QAEA,OAAO;AAAA,UACL,UAAU;AAAA,YACR,IAAI;AAAA,YACJ,SAAS,CAAC,aAAa;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,SAAS,CAAC,QAA4B,YAA8B;AAClE,UAAI,WAAW,SAAS;AAEtB,iBAAS,WAAW,QAAQ,QAAQ,OAAO;AAAA,MAC7C;AAEA,aAAO,QAAQ,MAAM,8BAA8B,IAAI;AAAA,QACrD;AAAA,MACF;AAEA,aAAO,UAAU,KAAK;AAAA,QACpB,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,IAAI;AAAA,MACN,CAAC;AACD,aAAO,OAAO,MAAM,KAAK;AAAA,QACvB,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAC;AAED,YAAM,EAAE,UAAU,YAAY,IAAI;AAGlC,UAAI,YAAY,gBAAgB,UAAU;AACxC,eAAO,QAAQ,KAAK,IAAI,eAAe,CAAC;AAAA,MAC1C;AAEA,aAAO;AAAA,IACT;AAAA,EACF,CAA+B;AACjC;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-intlayer",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Webpack configuration for IntLayer using NextJS",
|
|
6
6
|
"keywords": [
|
|
@@ -57,33 +57,31 @@
|
|
|
57
57
|
},
|
|
58
58
|
"files": [
|
|
59
59
|
"./dist",
|
|
60
|
-
"./src",
|
|
61
|
-
"./bin",
|
|
62
60
|
"./package.json"
|
|
63
61
|
],
|
|
64
62
|
"dependencies": {
|
|
65
63
|
"@formatjs/intl-localematcher": "^0.5.4",
|
|
66
64
|
"negotiator": "^0.6.3",
|
|
67
65
|
"next": "14.1.4",
|
|
68
|
-
"webpack": "^5.
|
|
69
|
-
"@intlayer/chokidar": "^2.0.
|
|
70
|
-
"@intlayer/config": "^2.0.
|
|
71
|
-
"@intlayer/core": "^2.0.
|
|
72
|
-
"@intlayer/dictionaries-entry": "^2.0.
|
|
73
|
-
"@intlayer/webpack": "^2.0.
|
|
74
|
-
"intlayer": "^2.0.
|
|
75
|
-
"react-intlayer": "^2.0.
|
|
66
|
+
"webpack": "^5.92.1",
|
|
67
|
+
"@intlayer/chokidar": "^2.0.2",
|
|
68
|
+
"@intlayer/config": "^2.0.2",
|
|
69
|
+
"@intlayer/core": "^2.0.2",
|
|
70
|
+
"@intlayer/dictionaries-entry": "^2.0.2",
|
|
71
|
+
"@intlayer/webpack": "^2.0.2",
|
|
72
|
+
"intlayer": "^2.0.2",
|
|
73
|
+
"react-intlayer": "^2.0.2"
|
|
76
74
|
},
|
|
77
75
|
"devDependencies": {
|
|
78
76
|
"@types/negotiator": "^0.6.3",
|
|
79
|
-
"@types/node": "^20.
|
|
80
|
-
"@types/react": "^18.
|
|
81
|
-
"react": "^18.
|
|
77
|
+
"@types/node": "^20.14.9",
|
|
78
|
+
"@types/react": "^18.3.3",
|
|
79
|
+
"react": "^18.3.1",
|
|
82
80
|
"rimraf": "5.0.5",
|
|
83
|
-
"tsup": "^8.0
|
|
84
|
-
"typescript": "^5.
|
|
85
|
-
"@utils/eslint-config": "^1.0.
|
|
86
|
-
"@utils/ts-config": "^1.0.
|
|
81
|
+
"tsup": "^8.1.0",
|
|
82
|
+
"typescript": "^5.5.2",
|
|
83
|
+
"@utils/eslint-config": "^1.0.2",
|
|
84
|
+
"@utils/ts-config": "^1.0.2"
|
|
87
85
|
},
|
|
88
86
|
"peerDependencies": {
|
|
89
87
|
"react": "^18.2.0"
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
export {
|
|
2
2
|
getTranslation,
|
|
3
|
-
|
|
4
|
-
IntlayerClient,
|
|
3
|
+
IntlayerClientContext,
|
|
5
4
|
useIntlayer,
|
|
6
5
|
useTraduction,
|
|
7
6
|
useLocaleCookie,
|
|
7
|
+
type IntlayerNode,
|
|
8
8
|
} from 'react-intlayer';
|
|
9
9
|
export { generateStaticParams } from './generateStaticParams';
|
|
10
10
|
export type { LocalParams, NextPageIntlayer } from './types/index';
|
|
11
|
-
export {
|
|
11
|
+
export {
|
|
12
|
+
useLocale,
|
|
13
|
+
IntlayerClientProvider,
|
|
14
|
+
type IntlayerClientProviderProps,
|
|
15
|
+
} from './client/index';
|
package/src/client/index.ts
DELETED
package/src/client/useLocale.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { type Locales, getConfiguration } from '@intlayer/config/client';
|
|
2
|
-
import { usePathname, useRouter } from 'next/navigation.js';
|
|
3
|
-
import { useLocaleCookie, useLocaleBase } from 'react-intlayer';
|
|
4
|
-
|
|
5
|
-
export const useLocale = () => {
|
|
6
|
-
const { prefixDefault } = getConfiguration().middleware;
|
|
7
|
-
const { setLocaleCookie } = useLocaleCookie();
|
|
8
|
-
const reactLocaleHook = useLocaleBase();
|
|
9
|
-
const router = useRouter();
|
|
10
|
-
const pathname = usePathname();
|
|
11
|
-
|
|
12
|
-
const {
|
|
13
|
-
defaultLocale,
|
|
14
|
-
availableLocales,
|
|
15
|
-
locale: currentLocale,
|
|
16
|
-
} = reactLocaleHook;
|
|
17
|
-
|
|
18
|
-
const setLocale = (locale: Locales) => {
|
|
19
|
-
if (currentLocale.toString() === locale.toString()) return;
|
|
20
|
-
|
|
21
|
-
if (!availableLocales.includes(locale)) {
|
|
22
|
-
console.error(`Locale ${locale} is not available`);
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
setLocaleCookie(locale);
|
|
27
|
-
|
|
28
|
-
const pathWithoutLocale =
|
|
29
|
-
!prefixDefault && currentLocale.toString() === defaultLocale.toString()
|
|
30
|
-
? pathname
|
|
31
|
-
: pathname.slice(`/${currentLocale}`.length) || '/';
|
|
32
|
-
|
|
33
|
-
if (!prefixDefault && locale === defaultLocale) {
|
|
34
|
-
return router.push(pathWithoutLocale);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return router.push(`/${locale}${pathWithoutLocale}`);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
...reactLocaleHook,
|
|
42
|
-
setLocale,
|
|
43
|
-
};
|
|
44
|
-
};
|
package/src/middleware/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './intlayerMiddleware';
|
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
import { type Locales, getConfiguration } from '@intlayer/config/client';
|
|
2
|
-
import { type NextRequest, NextResponse } from 'next/server';
|
|
3
|
-
import { localeDetector } from './localeDetector';
|
|
4
|
-
|
|
5
|
-
const { internationalization, middleware } = getConfiguration();
|
|
6
|
-
const { locales, defaultLocale } = internationalization;
|
|
7
|
-
const {
|
|
8
|
-
headerName,
|
|
9
|
-
cookieName,
|
|
10
|
-
prefixDefault,
|
|
11
|
-
basePath,
|
|
12
|
-
serverSetCookie,
|
|
13
|
-
noPrefix,
|
|
14
|
-
} = middleware;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Middleware that handles the internationalization layer
|
|
18
|
-
*
|
|
19
|
-
* Usage:
|
|
20
|
-
*
|
|
21
|
-
* // ./src/middleware.ts
|
|
22
|
-
*
|
|
23
|
-
* ```ts
|
|
24
|
-
* export { intlayerMiddleware as middleware } from '@intlayer/next/middleware';
|
|
25
|
-
*
|
|
26
|
-
* // applies this middleware only to files in the app directory
|
|
27
|
-
* export const config = {
|
|
28
|
-
* matcher: '/((?!api|static|.*\\..*|_next).*)',
|
|
29
|
-
* };
|
|
30
|
-
* ```
|
|
31
|
-
*
|
|
32
|
-
*/
|
|
33
|
-
export const intlayerMiddleware = (request: NextRequest): NextResponse => {
|
|
34
|
-
const pathname = request.nextUrl.pathname;
|
|
35
|
-
const cookieLocale = getCookieLocale(request);
|
|
36
|
-
const basePathTrailingSlash = basePath.endsWith('/');
|
|
37
|
-
|
|
38
|
-
if (noPrefix) {
|
|
39
|
-
return handleNoPrefix(
|
|
40
|
-
request,
|
|
41
|
-
cookieLocale,
|
|
42
|
-
pathname,
|
|
43
|
-
basePathTrailingSlash
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const pathLocale = getPathLocale(pathname);
|
|
48
|
-
return handlePrefix(
|
|
49
|
-
request,
|
|
50
|
-
cookieLocale,
|
|
51
|
-
pathLocale,
|
|
52
|
-
pathname,
|
|
53
|
-
basePathTrailingSlash
|
|
54
|
-
);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const getCookieLocale = (request: NextRequest): Locales | undefined => {
|
|
58
|
-
if (!cookieName) return undefined;
|
|
59
|
-
const cookieValue = request.cookies.get(cookieName)?.value as Locales;
|
|
60
|
-
if (cookieValue && locales.includes(cookieValue)) {
|
|
61
|
-
return cookieValue;
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const handleNoPrefix = (
|
|
66
|
-
request: NextRequest,
|
|
67
|
-
cookieLocale: Locales | undefined,
|
|
68
|
-
pathname: string,
|
|
69
|
-
basePathTrailingSlash: boolean
|
|
70
|
-
): NextResponse => {
|
|
71
|
-
const locale = cookieLocale ?? defaultLocale;
|
|
72
|
-
const newPath = constructPath(
|
|
73
|
-
locale,
|
|
74
|
-
pathname,
|
|
75
|
-
basePath,
|
|
76
|
-
basePathTrailingSlash
|
|
77
|
-
);
|
|
78
|
-
return rewriteUrl(request, newPath, locale);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const getPathLocale = (pathname: string): Locales | undefined =>
|
|
82
|
-
locales.find(
|
|
83
|
-
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
const handlePrefix = (
|
|
87
|
-
request: NextRequest,
|
|
88
|
-
cookieLocale: Locales | undefined,
|
|
89
|
-
pathLocale: Locales | undefined,
|
|
90
|
-
pathname: string,
|
|
91
|
-
basePathTrailingSlash: boolean
|
|
92
|
-
): NextResponse => {
|
|
93
|
-
if (!pathLocale) {
|
|
94
|
-
return handleMissingPathLocale(
|
|
95
|
-
request,
|
|
96
|
-
cookieLocale,
|
|
97
|
-
pathname,
|
|
98
|
-
basePathTrailingSlash
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
return handleExistingPathLocale(
|
|
102
|
-
request,
|
|
103
|
-
cookieLocale,
|
|
104
|
-
pathLocale,
|
|
105
|
-
pathname,
|
|
106
|
-
basePathTrailingSlash
|
|
107
|
-
);
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const handleMissingPathLocale = (
|
|
111
|
-
request: NextRequest,
|
|
112
|
-
cookieLocale: Locales | undefined,
|
|
113
|
-
pathname: string,
|
|
114
|
-
basePathTrailingSlash: boolean
|
|
115
|
-
): NextResponse => {
|
|
116
|
-
let locale = cookieLocale ?? localeDetector?.(request) ?? defaultLocale;
|
|
117
|
-
if (!locales.includes(locale)) {
|
|
118
|
-
console.warn(
|
|
119
|
-
'The localeDetector callback must return a locale included in your locales array. Reverting to using defaultLocale.'
|
|
120
|
-
);
|
|
121
|
-
locale = defaultLocale;
|
|
122
|
-
}
|
|
123
|
-
const newPath = constructPath(
|
|
124
|
-
locale,
|
|
125
|
-
pathname,
|
|
126
|
-
basePath,
|
|
127
|
-
basePathTrailingSlash
|
|
128
|
-
);
|
|
129
|
-
return prefixDefault || locale !== defaultLocale
|
|
130
|
-
? redirectUrl(request, newPath)
|
|
131
|
-
: rewriteUrl(request, newPath, locale);
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const handleExistingPathLocale = (
|
|
135
|
-
request: NextRequest,
|
|
136
|
-
cookieLocale: Locales | undefined,
|
|
137
|
-
pathLocale: Locales,
|
|
138
|
-
pathname: string,
|
|
139
|
-
basePathTrailingSlash: boolean
|
|
140
|
-
): NextResponse => {
|
|
141
|
-
if (
|
|
142
|
-
cookieLocale &&
|
|
143
|
-
cookieLocale !== pathLocale &&
|
|
144
|
-
serverSetCookie !== 'always'
|
|
145
|
-
) {
|
|
146
|
-
const newPath = handleCookieLocaleMismatch(
|
|
147
|
-
request,
|
|
148
|
-
pathname,
|
|
149
|
-
pathLocale,
|
|
150
|
-
cookieLocale,
|
|
151
|
-
basePath,
|
|
152
|
-
basePathTrailingSlash
|
|
153
|
-
);
|
|
154
|
-
return redirectUrl(request, newPath);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return handleDefaultLocaleRedirect(
|
|
158
|
-
request,
|
|
159
|
-
pathLocale,
|
|
160
|
-
pathname,
|
|
161
|
-
basePathTrailingSlash
|
|
162
|
-
);
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
const handleCookieLocaleMismatch = (
|
|
166
|
-
request: NextRequest,
|
|
167
|
-
|
|
168
|
-
pathname: string,
|
|
169
|
-
pathLocale: Locales,
|
|
170
|
-
cookieLocale: Locales,
|
|
171
|
-
basePath: string,
|
|
172
|
-
basePathTrailingSlash: boolean
|
|
173
|
-
): string => {
|
|
174
|
-
const newPath = pathname.replace(`/${pathLocale}`, `/${cookieLocale}`);
|
|
175
|
-
return constructPath(
|
|
176
|
-
cookieLocale,
|
|
177
|
-
newPath,
|
|
178
|
-
basePath,
|
|
179
|
-
basePathTrailingSlash,
|
|
180
|
-
request.nextUrl.search
|
|
181
|
-
);
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
const handleDefaultLocaleRedirect = (
|
|
185
|
-
request: NextRequest,
|
|
186
|
-
pathLocale: Locales,
|
|
187
|
-
pathname: string,
|
|
188
|
-
basePathTrailingSlash: boolean
|
|
189
|
-
): NextResponse => {
|
|
190
|
-
if (!prefixDefault && pathLocale === defaultLocale) {
|
|
191
|
-
let pathWithoutLocale = pathname.slice(`/${pathLocale}`.length) || '/';
|
|
192
|
-
|
|
193
|
-
if (basePathTrailingSlash) {
|
|
194
|
-
pathWithoutLocale = pathWithoutLocale.slice(1);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (request.nextUrl.search) {
|
|
198
|
-
pathWithoutLocale += request.nextUrl.search;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
return rewriteUrl(request, `${basePath}${pathWithoutLocale}`, pathLocale);
|
|
202
|
-
}
|
|
203
|
-
return rewriteUrl(request, pathname, pathLocale);
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
const constructPath = (
|
|
207
|
-
locale: Locales,
|
|
208
|
-
path: string,
|
|
209
|
-
basePath: string,
|
|
210
|
-
basePathTrailingSlash: boolean,
|
|
211
|
-
search?: string
|
|
212
|
-
): string => {
|
|
213
|
-
let newPath = `${locale}${path}`;
|
|
214
|
-
newPath = `${basePath}${basePathTrailingSlash ? '' : '/'}${newPath}`;
|
|
215
|
-
if (search) {
|
|
216
|
-
newPath += search;
|
|
217
|
-
}
|
|
218
|
-
return newPath;
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
const rewriteUrl = (
|
|
222
|
-
request: NextRequest,
|
|
223
|
-
newPath: string,
|
|
224
|
-
locale: Locales
|
|
225
|
-
): NextResponse => {
|
|
226
|
-
const response = NextResponse.rewrite(new URL(newPath, request.url));
|
|
227
|
-
response.headers.set(headerName, locale);
|
|
228
|
-
return response;
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
const redirectUrl = (request: NextRequest, newPath: string): NextResponse =>
|
|
232
|
-
NextResponse.redirect(new URL(newPath, request.url));
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { match } from '@formatjs/intl-localematcher';
|
|
2
|
-
import type { Locales } from '@intlayer/config';
|
|
3
|
-
import { getConfiguration } from '@intlayer/config/client';
|
|
4
|
-
import Negotiator from 'negotiator';
|
|
5
|
-
import type { NextRequest } from 'next/server.js';
|
|
6
|
-
|
|
7
|
-
const { locales, defaultLocale } = getConfiguration().internationalization;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Detects the locale from the request headers
|
|
11
|
-
*
|
|
12
|
-
* Headers are provided by the browser and can be used to determine the user's preferred language
|
|
13
|
-
*/
|
|
14
|
-
export const localeDetector = (request: NextRequest): Locales => {
|
|
15
|
-
const negotiatorHeaders: Record<string, string> = {};
|
|
16
|
-
|
|
17
|
-
request.headers.forEach((value, key) => (negotiatorHeaders[key] = value));
|
|
18
|
-
|
|
19
|
-
const languages = new Negotiator({ headers: negotiatorHeaders }).languages();
|
|
20
|
-
|
|
21
|
-
// match can only use specifically formatted locales
|
|
22
|
-
// https://stackoverflow.com/questions/76447732/nextjs-13-i18n-incorrect-locale-information-provided
|
|
23
|
-
try {
|
|
24
|
-
return match(languages, locales, defaultLocale) as Locales;
|
|
25
|
-
} catch (e) {
|
|
26
|
-
console.warn(
|
|
27
|
-
`No valid locales in accept-language header: ${languages.join(', ')}`
|
|
28
|
-
);
|
|
29
|
-
console.warn(`Reverting to using defaultLocale: ${defaultLocale}`);
|
|
30
|
-
|
|
31
|
-
return defaultLocale;
|
|
32
|
-
}
|
|
33
|
-
};
|
package/src/server/index.ts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { resolve, relative, join } from 'path';
|
|
2
|
-
import { getConfiguration, formatEnvVariable } from '@intlayer/config';
|
|
3
|
-
import { IntLayerPlugin } from '@intlayer/webpack';
|
|
4
|
-
import type { NextConfig } from 'next';
|
|
5
|
-
import type { NextJsWebpackConfig } from 'next/dist/server/config-shared';
|
|
6
|
-
|
|
7
|
-
type PluginOptions = {
|
|
8
|
-
// TODO: add options
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
type WebpackParams = Parameters<NextJsWebpackConfig>;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* A Next.js plugin that adds the intlayer configuration to the webpack configuration
|
|
15
|
-
* and sets the environment variables
|
|
16
|
-
*
|
|
17
|
-
* Usage:
|
|
18
|
-
*
|
|
19
|
-
* ```ts
|
|
20
|
-
* // next.config.js
|
|
21
|
-
* export default withIntlayer(nextConfig)
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
*/
|
|
25
|
-
export const withIntlayer =
|
|
26
|
-
(_pluginOptions: PluginOptions = {}) =>
|
|
27
|
-
(nextConfig: Partial<NextConfig> = {}): Partial<NextConfig> => {
|
|
28
|
-
if (typeof nextConfig !== 'object') nextConfig = {};
|
|
29
|
-
|
|
30
|
-
const intlayerConfig = getConfiguration();
|
|
31
|
-
|
|
32
|
-
// Set all configuration values as environment variables
|
|
33
|
-
const env = formatEnvVariable('next');
|
|
34
|
-
|
|
35
|
-
const { mainDir, baseDir } = intlayerConfig.content;
|
|
36
|
-
const dictionariesPath = join(mainDir, 'dictionaries.mjs');
|
|
37
|
-
const relativeDictionariesPath = relative(baseDir, dictionariesPath);
|
|
38
|
-
|
|
39
|
-
return Object.assign({}, nextConfig, {
|
|
40
|
-
env: { ...nextConfig.env, ...env },
|
|
41
|
-
|
|
42
|
-
experimental: {
|
|
43
|
-
...(nextConfig.experimental ?? {}),
|
|
44
|
-
// Using Intlayer with Turbopack is not supported as long external modules can't be resolved (such as esbuild or fs)
|
|
45
|
-
turbo: {
|
|
46
|
-
...(nextConfig.experimental?.turbo ?? {}),
|
|
47
|
-
resolveAlias: {
|
|
48
|
-
...nextConfig.experimental?.turbo?.resolveAlias,
|
|
49
|
-
'@intlayer/dictionaries-entry': resolve(relativeDictionariesPath),
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
rules: {
|
|
53
|
-
'*.node': {
|
|
54
|
-
as: '*.node',
|
|
55
|
-
loaders: ['node-loader'],
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
webpack: (
|
|
62
|
-
config: WebpackParams['0'],
|
|
63
|
-
{ isServer, nextRuntime }: WebpackParams[1]
|
|
64
|
-
) => {
|
|
65
|
-
config.resolve.alias['@intlayer/dictionaries-entry'] = resolve(
|
|
66
|
-
relativeDictionariesPath
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
config.externals.push({
|
|
70
|
-
esbuild: 'esbuild',
|
|
71
|
-
module: 'module',
|
|
72
|
-
fs: 'fs',
|
|
73
|
-
});
|
|
74
|
-
config.module.rules.push({
|
|
75
|
-
test: /\.node$/,
|
|
76
|
-
loader: 'node-loader',
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// Apply IntLayerPlugin only on the server-side
|
|
80
|
-
if (isServer && nextRuntime === 'nodejs') {
|
|
81
|
-
config.plugins.push(new IntLayerPlugin());
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return config;
|
|
85
|
-
},
|
|
86
|
-
} satisfies Partial<NextConfig>);
|
|
87
|
-
};
|
package/src/types/NextPage.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { Locales } from 'intlayer';
|
|
2
|
-
import type { NextPage } from 'next';
|
|
3
|
-
import type { PropsWithChildren } from 'react';
|
|
4
|
-
|
|
5
|
-
export type LocalParams = {
|
|
6
|
-
params: { locale: Locales };
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export type NextPageIntlayer = NextPage<LocalParams>;
|
|
10
|
-
export type NextLayoutIntlayer = NextPage<PropsWithChildren<LocalParams>>;
|
package/src/types/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type { LocalParams, NextPageIntlayer } from './NextPage';
|