cloudflare-next-intl-intl 0.0.0-stage → 0.2.0

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.
Files changed (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +279 -2
  3. package/dist/package.json +3 -0
  4. package/dist/src/client/components/client_provider.d.ts +8 -0
  5. package/dist/src/client/components/client_provider.js +12 -0
  6. package/dist/src/client/components/client_provider_static.d.ts +8 -0
  7. package/dist/src/client/components/client_provider_static.js +12 -0
  8. package/dist/src/client/components/locale_link.d.ts +8 -0
  9. package/dist/src/client/components/locale_link.js +8 -0
  10. package/dist/src/client/components/locale_link_client.d.ts +3 -0
  11. package/dist/src/client/components/locale_link_client.js +30 -0
  12. package/dist/src/client/components/locale_provider.d.ts +13 -0
  13. package/dist/src/client/components/locale_provider.js +8 -0
  14. package/dist/src/client/functions/get_cookie.d.ts +1 -0
  15. package/dist/src/client/functions/get_cookie.js +27 -0
  16. package/dist/src/client/functions/set_cookie.d.ts +5 -0
  17. package/dist/src/client/functions/set_cookie.js +12 -0
  18. package/dist/src/client/hooks/client_hooks.d.ts +3 -0
  19. package/dist/src/client/hooks/client_hooks.js +19 -0
  20. package/dist/src/client/hooks/use_path_name.d.ts +2 -0
  21. package/dist/src/client/hooks/use_path_name.js +18 -0
  22. package/dist/src/client/index.d.ts +4 -0
  23. package/dist/src/client/index.js +4 -0
  24. package/dist/src/client_messages_scan/index.d.ts +3 -0
  25. package/dist/src/client_messages_scan/index.js +3 -0
  26. package/dist/src/client_messages_scan/match_namespace.d.ts +1 -0
  27. package/dist/src/client_messages_scan/match_namespace.js +3 -0
  28. package/dist/src/client_messages_scan/scan_file.d.ts +16 -0
  29. package/dist/src/client_messages_scan/scan_file.js +182 -0
  30. package/dist/src/client_messages_scan/scan_project.d.ts +16 -0
  31. package/dist/src/client_messages_scan/scan_project.js +67 -0
  32. package/dist/src/config/cookie_key.d.ts +4 -0
  33. package/dist/src/config/cookie_key.js +4 -0
  34. package/dist/src/config/create_intl_middleware.d.ts +16 -0
  35. package/dist/src/config/create_intl_middleware.js +174 -0
  36. package/dist/src/config/index.d.ts +4 -0
  37. package/dist/src/config/index.js +4 -0
  38. package/dist/src/config/init_config.d.ts +2 -0
  39. package/dist/src/config/init_config.js +3 -0
  40. package/dist/src/config/intl_config.d.ts +3 -0
  41. package/dist/src/config/intl_config.js +22 -0
  42. package/dist/src/config/intl_sitemap.d.ts +8 -0
  43. package/dist/src/config/intl_sitemap.js +28 -0
  44. package/dist/src/config/middleware.d.ts +7 -0
  45. package/dist/src/config/middleware.js +4 -0
  46. package/dist/src/general/cache_variables.d.ts +10 -0
  47. package/dist/src/general/cache_variables.js +25 -0
  48. package/dist/src/general/general_functions.d.ts +2 -0
  49. package/dist/src/general/general_functions.js +106 -0
  50. package/dist/src/general/index.d.ts +2 -0
  51. package/dist/src/general/index.js +2 -0
  52. package/dist/src/general/metadata.d.ts +13 -0
  53. package/dist/src/general/metadata.js +25 -0
  54. package/dist/src/general/pick_client_messages.d.ts +2 -0
  55. package/dist/src/general/pick_client_messages.js +17 -0
  56. package/dist/src/general/report_intl_error.d.ts +1 -0
  57. package/dist/src/general/report_intl_error.js +15 -0
  58. package/dist/src/index.d.ts +5 -0
  59. package/dist/src/index.js +5 -0
  60. package/dist/src/server/components/helper_script.d.ts +6 -0
  61. package/dist/src/server/components/helper_script.js +39 -0
  62. package/dist/src/server/components/link.d.ts +10 -0
  63. package/dist/src/server/components/link.js +143 -0
  64. package/dist/src/server/components/server_provider.d.ts +8 -0
  65. package/dist/src/server/components/server_provider.js +24 -0
  66. package/dist/src/server/components/server_provider_static.d.ts +6 -0
  67. package/dist/src/server/components/server_provider_static.js +23 -0
  68. package/dist/src/server/functions/geo.d.ts +8 -0
  69. package/dist/src/server/functions/geo.js +223 -0
  70. package/dist/src/server/functions/get_user_locale.d.ts +3 -0
  71. package/dist/src/server/functions/get_user_locale.js +34 -0
  72. package/dist/src/server/functions/locale_static_params.d.ts +3 -0
  73. package/dist/src/server/functions/locale_static_params.js +4 -0
  74. package/dist/src/server/functions/server.d.ts +8 -0
  75. package/dist/src/server/functions/server.js +64 -0
  76. package/dist/src/server/functions/use_functions.d.ts +6 -0
  77. package/dist/src/server/functions/use_functions.js +30 -0
  78. package/dist/src/server/index.d.ts +6 -0
  79. package/dist/src/server/index.js +6 -0
  80. package/dist/src/types/index.d.ts +1 -0
  81. package/dist/src/types/index.js +1 -0
  82. package/dist/src/types/types.d.ts +94 -0
  83. package/dist/src/types/types.js +3 -0
  84. package/llms.txt +17 -0
  85. package/package.json +282 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Demian
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,280 @@
1
- # Temporary Holding Version
1
+ # cloudflare-next-intl-intl
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![npm](https://img.shields.io/npm/v/cloudflare-next-intl-intl.svg)](https://www.npmjs.com/package/cloudflare-next-intl-intl)
4
+ [![license](https://img.shields.io/npm/l/cloudflare-next-intl-intl.svg)](./LICENSE)
5
+
6
+ Lightweight internationalization (i18n) for the **Next.js App Router**, built for
7
+ **Cloudflare Workers / Pages** (OpenNext and Vinext).
8
+
9
+ This is the core i18n engine of [`cloudflare-next-intl`](https://www.npmjs.com/package/cloudflare-next-intl),
10
+ published on its own with **zero runtime dependencies** and no auth, cookie-consent,
11
+ image or database code. Use it when you only need routing + translations; use
12
+ `cloudflare-next-intl` when you also want those extras auto-wired.
13
+
14
+ ## Features
15
+
16
+ - Locale routing middleware (prefix redirects/rewrites, cookie + `Accept-Language` detection).
17
+ - Translations in Server Components (`getTranslations`) and Client Components (`useTranslations`).
18
+ - Ships only the message namespaces your client components need (`clientMessages`).
19
+ - Locale-aware `Link` / `LocaleLink`, `usePathname`, `getLocale`, `useLocale`.
20
+ - Cloudflare geo helpers: `getCountry`, `getTimezone`.
21
+ - SEO helpers: `hreflang` / canonical alternates via `alternatesLinks`.
22
+ - One subpath export per feature, so unused code is tree-shaken away.
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ npm install cloudflare-next-intl-intl
28
+ ```
29
+
30
+ Peer dependencies: `next` (>= 12) and `react` (>= 16.8).
31
+
32
+ ## Setup
33
+
34
+ The package finds your config through the `@intl-config` module alias and your
35
+ message files through `@locale-file`.
36
+
37
+ ### 1. Create the config file
38
+
39
+ ```ts
40
+ // src/i18n/intl_config.ts
41
+ import { setIntlConfig } from "cloudflare-next-intl-intl/setIntlConfig";
42
+
43
+ export default setIntlConfig({
44
+ locales: ["en", "de"],
45
+ defaultLocale: "en",
46
+ });
47
+ ```
48
+
49
+ ### 2. Add message files
50
+
51
+ One JSON file per locale, named `<locale>.json`:
52
+
53
+ ```
54
+ src/i18n/messages/en.json
55
+ src/i18n/messages/de.json
56
+ ```
57
+
58
+ ```json
59
+ {
60
+ "Index": {
61
+ "title": "Hello world",
62
+ "items": ["One", "Two"]
63
+ }
64
+ }
65
+ ```
66
+
67
+ ### 3. Add the aliases in `next.config`
68
+
69
+ Set them for both Turbopack and webpack. If one is missing, the build that uses
70
+ that bundler fails.
71
+
72
+ ```ts
73
+ // next.config.ts
74
+ import type { NextConfig } from "next";
75
+ import path from "path";
76
+
77
+ const nextConfig: NextConfig = {
78
+ turbopack: {
79
+ resolveAlias: {
80
+ "@intl-config": "./src/i18n/intl_config.ts",
81
+ "@locale-file": "./src/i18n/messages",
82
+ },
83
+ },
84
+ webpack(config) {
85
+ config.resolve.alias = {
86
+ ...config.resolve.alias,
87
+ "@intl-config": path.resolve(__dirname, "src/i18n/intl_config"),
88
+ "@locale-file": path.resolve(__dirname, "src/i18n/messages"),
89
+ };
90
+ return config;
91
+ },
92
+ };
93
+
94
+ export default nextConfig;
95
+ ```
96
+
97
+ If you deploy to Cloudflare Workers with Wrangler, add the same aliases to `wrangler.toml`:
98
+
99
+ ```toml
100
+ [alias]
101
+ "@intl-config" = "./src/i18n/intl_config.ts"
102
+ "@locale-file" = "./src/i18n/messages"
103
+ ```
104
+
105
+ ### 4. Add the middleware
106
+
107
+ ```ts
108
+ // src/middleware.ts
109
+ import intlMiddleware from "cloudflare-next-intl-intl/middleware";
110
+
111
+ export const middleware = intlMiddleware;
112
+
113
+ export const config = {
114
+ matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
115
+ };
116
+ ```
117
+
118
+ To run your own logic (auth, feature flags, A/B tests) on each request, pass a `middlewareHandler`:
119
+
120
+ ```ts
121
+ export function middleware(request: NextRequest) {
122
+ return intlMiddleware(request, {
123
+ middlewareHandler: (locale, rewriteUrl, redirectUrl) => {
124
+ return null; // return a NextResponse to override, or null to keep the default
125
+ },
126
+ });
127
+ }
128
+ ```
129
+
130
+ If you need the final response, for example to update session cookies, build
131
+ your own middleware with `createIntlMiddleware({ afterResponse })`.
132
+
133
+ ### 5. Set up the root layout
134
+
135
+ ```tsx
136
+ // src/app/[locale]/layout.tsx
137
+ import { IntlProvider, IntlHelperScript, getLocaleStaticParams } from "cloudflare-next-intl-intl/server";
138
+
139
+ export const generateStaticParams = getLocaleStaticParams;
140
+
141
+ export default async function RootLayout({ children, params }) {
142
+ const { locale } = await params;
143
+ return (
144
+ <html lang={locale}>
145
+ <head>
146
+ <IntlHelperScript locale={locale} />
147
+ </head>
148
+ <body>
149
+ <IntlProvider language={locale}>{children}</IntlProvider>
150
+ </body>
151
+ </html>
152
+ );
153
+ }
154
+ ```
155
+
156
+ If you build with `output: "export"`, import `IntlProvider` from
157
+ `cloudflare-next-intl-intl/serverProviderStatic` instead.
158
+
159
+ ## Usage
160
+
161
+ ### Server Components
162
+
163
+ ```tsx
164
+ import { getTranslations, getLocale } from "cloudflare-next-intl-intl/server";
165
+
166
+ export default async function Page() {
167
+ const t = await getTranslations("Index");
168
+ const locale = await getLocale();
169
+ const items = t.raw("items") as string[];
170
+
171
+ return <h1>{t("title")} ({locale})</h1>;
172
+ }
173
+ ```
174
+
175
+ `t(key)` always returns a string. For arrays or nested objects, use `t.raw(key)`.
176
+
177
+ ### Client Components
178
+
179
+ ```tsx
180
+ "use client";
181
+
182
+ import { useTranslations, useLocale } from "cloudflare-next-intl-intl/use";
183
+
184
+ export function Title() {
185
+ const t = useTranslations("Index");
186
+ const locale = useLocale();
187
+ return <h1>{t("title")} ({locale})</h1>;
188
+ }
189
+ ```
190
+
191
+ `cloudflare-next-intl-intl/use` works in both Server and Client Components and
192
+ picks the right implementation automatically.
193
+
194
+ By default (`clientMessages: "auto"`), only the namespaces your client
195
+ components use are sent to the browser. You can set this in `setIntlConfig`:
196
+
197
+ - `clientMessages: false`: send no messages to the browser.
198
+ - `clientMessages: true`: send all messages.
199
+ - `clientMessages: ["Common", "Auth*"]`: send only the listed namespaces (prefix wildcards allowed).
200
+
201
+ ### Links
202
+
203
+ ```tsx
204
+ import Link from "cloudflare-next-intl-intl/Link";
205
+ import LocaleLink from "cloudflare-next-intl-intl/LocaleLink";
206
+
207
+ <Link href="/about">About</Link> // stays on the current locale: "/about" or "/de/about"
208
+ <LocaleLink href="/" locale="de">Deutsch</LocaleLink> // client-only, switches the locale
209
+ ```
210
+
211
+ `usePathname` (`cloudflare-next-intl-intl/usePathname`) returns the current path
212
+ without the locale prefix.
213
+
214
+ ### Geo & timezone (Cloudflare)
215
+
216
+ ```tsx
217
+ import { getCountry, getTimezone } from "cloudflare-next-intl-intl/geo";
218
+
219
+ const country = await getCountry(); // "US", "DE", "UA", ...
220
+ const timezone = await getTimezone(undefined, "UTC");
221
+ ```
222
+
223
+ These work in Server Components, Server Actions, Route Handlers, and middleware
224
+ (pass `request` there). The middleware forwards the Cloudflare
225
+ `x-cf-country` / `x-cf-timezone` headers, so these values are also available
226
+ further down the request. You can change the header names with
227
+ `generate.countryHeaderNames` / `generate.timezoneHeaderNames`.
228
+
229
+ ### SEO metadata
230
+
231
+ ```ts
232
+ import { alternatesLinks } from "cloudflare-next-intl-intl/metadata";
233
+
234
+ export async function generateMetadata({ params }) {
235
+ const { locale } = await params;
236
+ return {
237
+ alternates: alternatesLinks({ url: "https://example.com", locale, linkPart: "/about" }),
238
+ };
239
+ }
240
+ ```
241
+
242
+ ### Cookies
243
+
244
+ ```ts
245
+ import setCookie from "cloudflare-next-intl-intl/setCookie";
246
+ import getCookie from "cloudflare-next-intl-intl/getCookie";
247
+ ```
248
+
249
+ ## Public subpath exports
250
+
251
+ | Subpath | Contents |
252
+ | --- | --- |
253
+ | `.` | Everything below (prefer the specific subpaths for tree-shaking) |
254
+ | `./setIntlConfig` | `setIntlConfig` |
255
+ | `./middleware` | default `intlMiddleware`, `createIntlMiddleware` |
256
+ | `./server` | `getTranslations`, `getLocale`, `getMessage`, `IntlProvider`, `Link`, `IntlHelperScript`, `getLocaleStaticParams`, `getCountry`, `getTimezone` |
257
+ | `./client` | `LocaleLink`, `usePathname`, `setCookieClient`, `getCookieClient` |
258
+ | `./use` | `useTranslations`, `useLocale` (works in Server and Client Components) |
259
+ | `./serverProvider`, `./serverProviderStatic` | `IntlProvider` variants |
260
+ | `./Link`, `./LocaleLink`, `./usePathname`, `./IntlHelperScript` | Single components / hooks |
261
+ | `./geo`, `./getCountry`, `./getTimezone` | Geo helpers |
262
+ | `./metadata` | `alternatesLinks`, `languages` |
263
+ | `./localeStaticParams` | `getLocaleStaticParams` |
264
+ | `./setCookie`, `./getCookie`, `./setCookieClient`, `./getCookieClient` | Cookie helpers |
265
+ | `./types` | TypeScript types (`IntlRoutingConfig`, `RoutingConfig`, ...) |
266
+
267
+ `./internal/*` subpaths are only for wrapper packages such as
268
+ `cloudflare-next-intl` and `cloudflare-next-intl-auth`. Don't import them in
269
+ your app; they can change in any release.
270
+
271
+ ## Related packages
272
+
273
+ - [`cloudflare-next-intl`](https://www.npmjs.com/package/cloudflare-next-intl): all-in-one package (i18n + auth + cookie consent + theme + errors + images + DB), auto-wired.
274
+ - [`cloudflare-next-intl-errors`](https://www.npmjs.com/package/cloudflare-next-intl-errors): Error reporting, overrides, and stale-deploy recovery.
275
+ - [`cloudflare-next-intl-theme`](https://www.npmjs.com/package/cloudflare-next-intl-theme): Theme switcher and dark mode cookies.
276
+ - [`cloudflare-next-intl-auth`](https://www.npmjs.com/package/cloudflare-next-intl-auth): Firebase Auth & App Check built on this package.
277
+
278
+ ## License
279
+
280
+ MIT
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,8 @@
1
+ import type { TranslationObject } from "../../types/types.js";
2
+ import { LocaleContext } from "./locale_provider.js";
3
+ export { LocaleContext };
4
+ export default function LocationzationClientProvider({ language, messages, children, }: {
5
+ language: string;
6
+ messages: TranslationObject;
7
+ children?: React.ReactNode;
8
+ }): import("react").JSX.Element;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { setLocaleCache, setMessageForLocaleCache } from "../../general/cache_variables.js";
4
+ import { useMemo } from "react";
5
+ import { LocaleContext } from "./locale_provider.js";
6
+ export { LocaleContext };
7
+ export default function LocationzationClientProvider({ language, messages, children, }) {
8
+ setLocaleCache(language);
9
+ setMessageForLocaleCache(language, messages);
10
+ const contextValue = useMemo(() => ({ language, messages }), [language, messages]);
11
+ return (_jsx(LocaleContext.Provider, { value: contextValue, children: children }));
12
+ }
@@ -0,0 +1,8 @@
1
+ import type { TranslationObject } from "../../types/types.js";
2
+ import { LocaleContext } from "./locale_provider.js";
3
+ export { LocaleContext };
4
+ export default function LocationzationClientProvider({ language, messages, children, }: {
5
+ language: string;
6
+ messages: TranslationObject;
7
+ children: React.ReactNode;
8
+ }): import("react").JSX.Element;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { setLocaleCache, setMessageForLocaleCache } from "../../general/cache_variables.js";
4
+ import { useMemo } from "react";
5
+ import { LocaleContext } from "./locale_provider.js";
6
+ export { LocaleContext };
7
+ export default function LocationzationClientProvider({ language, messages, children, }) {
8
+ setLocaleCache(language);
9
+ setMessageForLocaleCache(language, messages);
10
+ const contextValue = useMemo(() => ({ language, messages }), [language, messages]);
11
+ return (_jsx(LocaleContext.Provider, { value: contextValue, children: children }));
12
+ }
@@ -0,0 +1,8 @@
1
+ import { type LinkProps } from 'next/link.js';
2
+ import { type ComponentProps } from 'react';
3
+ type NextLinkProps = Omit<ComponentProps<'a'>, keyof LinkProps> & Omit<LinkProps, 'locale' | 'href' | 'prefetch' | 'onNavigate' | 'hrefLang' | 'replace' | 'scroll'>;
4
+ export type LocaleLinkProps = NextLinkProps & {
5
+ locale: string;
6
+ };
7
+ declare const LocaleLink: import("react").ForwardRefExoticComponent<Omit<LocaleLinkProps, "ref"> & import("react").RefAttributes<HTMLAnchorElement>>;
8
+ export default LocaleLink;
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef, Suspense, } from 'react';
3
+ import LocaleLinkClient from './locale_link_client.js';
4
+ function LocaleLinkComponent(params, ref) {
5
+ return _jsx(Suspense, { fallback: _jsx("a", { ...params, ref: ref, className: params.className + ' pointer-events-none' }), children: _jsx(LocaleLinkClient, { ref: ref, ...params }) });
6
+ }
7
+ const LocaleLink = forwardRef(LocaleLinkComponent);
8
+ export default LocaleLink;
@@ -0,0 +1,3 @@
1
+ import type { LocaleLinkProps } from './locale_link.js';
2
+ declare const LocaleLinkClient: import("react").ForwardRefExoticComponent<Omit<LocaleLinkProps, "ref"> & import("react").RefAttributes<HTMLAnchorElement>>;
3
+ export default LocaleLinkClient;
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { forwardRef, useEffect, useState, } from 'react';
4
+ import config from '../../config/intl_config.js';
5
+ import usePathname from '../hooks/use_path_name.js';
6
+ import { localeCookieName } from '../../config/cookie_key.js';
7
+ import setCookie from '../functions/set_cookie.js';
8
+ import { useSearchParams } from 'next/navigation.js';
9
+ function ClientLocaleLinkComponent({ locale, className, ...rest }, ref) {
10
+ const pathname = usePathname();
11
+ const searchParams = useSearchParams();
12
+ const [hash, setHash] = useState('');
13
+ useEffect(() => {
14
+ setHash(window.location.hash);
15
+ }, [pathname, searchParams]);
16
+ const isDefaultLocale = locale === config.defaultLocale;
17
+ const localePrefix = isDefaultLocale ? '' : `/${locale}`;
18
+ const search = searchParams.toString();
19
+ const newPathname = pathname === '/' && (localePrefix) ? '' : pathname;
20
+ const href = `${localePrefix}${newPathname}${search ? `?${search}` : ''}${hash}`;
21
+ function handleNavigate(e) {
22
+ e.preventDefault();
23
+ setCookie({ name: localeCookieName, value: locale });
24
+ window.location.replace(href);
25
+ }
26
+ ;
27
+ return _jsx("a", { ref: ref, hrefLang: locale, className: className, ...rest, href: href, onClick: handleNavigate });
28
+ }
29
+ const LocaleLinkClient = forwardRef(ClientLocaleLinkComponent);
30
+ export default LocaleLinkClient;
@@ -0,0 +1,13 @@
1
+ import { type ReactNode } from "react";
2
+ import type { TranslationObject } from "../../types/types.js";
3
+ interface LocaleContextType {
4
+ language: string;
5
+ messages: TranslationObject;
6
+ }
7
+ export declare const LocaleContext: import("react").Context<LocaleContextType | undefined>;
8
+ export default function LocaleProvider({ language, messages, children }: {
9
+ language: string;
10
+ messages: TranslationObject;
11
+ children: ReactNode;
12
+ }): React.JSX.Element;
13
+ export {};
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useMemo } from "react";
4
+ export const LocaleContext = createContext(undefined);
5
+ export default function LocaleProvider({ language, messages, children }) {
6
+ const value = useMemo(() => ({ language, messages }), [language, messages]);
7
+ return _jsx(LocaleContext.Provider, { value: value, children: children });
8
+ }
@@ -0,0 +1 @@
1
+ export default function getCookie(name: string): string | null;
@@ -0,0 +1,27 @@
1
+ "use client";
2
+ import reportIntlError from "../../general/report_intl_error.js";
3
+ export default function getCookie(name) {
4
+ try {
5
+ const cookie = document.cookie;
6
+ const prefix = `${name}=`;
7
+ let start = -1;
8
+ if (cookie.startsWith(prefix)) {
9
+ start = prefix.length;
10
+ }
11
+ else {
12
+ const idx = cookie.indexOf(`; ${prefix}`);
13
+ if (idx !== -1)
14
+ start = idx + 2 + prefix.length;
15
+ }
16
+ if (start === -1)
17
+ return null;
18
+ const end = cookie.indexOf(';', start);
19
+ const value = end === -1 ? cookie.slice(start) : cookie.slice(start, end);
20
+ return decodeURIComponent(value);
21
+ }
22
+ catch (e) {
23
+ reportIntlError(e, 'getCookie');
24
+ return null;
25
+ }
26
+ }
27
+ ;
@@ -0,0 +1,5 @@
1
+ export default function setCookie({ name, value, maxAge }: {
2
+ name: string;
3
+ value: string | number | boolean;
4
+ maxAge?: number;
5
+ }): void;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import reportIntlError from "../../general/report_intl_error.js";
3
+ export default function setCookie({ name, value, maxAge }) {
4
+ try {
5
+ const cookieString = `${name}=${value}; path=/; max-age=${maxAge ?? 31536000}; SameSite=Lax;`;
6
+ document.cookie = cookieString;
7
+ }
8
+ catch (e) {
9
+ reportIntlError(e, 'setCookie');
10
+ }
11
+ }
12
+ ;
@@ -0,0 +1,3 @@
1
+ import type { TranslatorReturnType } from "../../types/types.js";
2
+ export declare function useLocale(): string;
3
+ export declare function useTranslations(namespace: string): TranslatorReturnType;
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { useContext, useMemo } from "react";
3
+ import { LocaleContext } from "../components/client_provider.js";
4
+ import { getTranslationsImpl } from "../../general/general_functions.js";
5
+ export function useLocale() {
6
+ const context = useContext(LocaleContext);
7
+ if (context === undefined) {
8
+ throw new Error('useLocale must be used within an IntlProvider');
9
+ }
10
+ return context.language;
11
+ }
12
+ export function useTranslations(namespace) {
13
+ const context = useContext(LocaleContext);
14
+ if (context === undefined) {
15
+ throw new Error('useTranslations must be used within an IntlProvider');
16
+ }
17
+ const { language, messages } = context;
18
+ return useMemo(() => getTranslationsImpl(language, messages, namespace), [language, messages, namespace]);
19
+ }
@@ -0,0 +1,2 @@
1
+ export default function usePathname(): string;
2
+ export { usePathname };
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { usePathname as nextUsePathname } from "next/navigation.js";
3
+ import { useLocale } from "./client_hooks.js";
4
+ export default function usePathname() {
5
+ const pathname = nextUsePathname();
6
+ const locale = useLocale();
7
+ if (!pathname) {
8
+ return '/';
9
+ }
10
+ const path = pathname.replace(`/${locale}`, '');
11
+ if (path) {
12
+ return path;
13
+ }
14
+ else {
15
+ return '/';
16
+ }
17
+ }
18
+ export { usePathname };
@@ -0,0 +1,4 @@
1
+ export { default as LocaleLink } from './components/locale_link.js';
2
+ export { default as usePathname } from './hooks/use_path_name.js';
3
+ export { default as setCookieClient } from './functions/set_cookie.js';
4
+ export { default as getCookieClient } from './functions/get_cookie.js';
@@ -0,0 +1,4 @@
1
+ export { default as LocaleLink } from './components/locale_link.js';
2
+ export { default as usePathname } from './hooks/use_path_name.js';
3
+ export { default as setCookieClient } from './functions/set_cookie.js';
4
+ export { default as getCookieClient } from './functions/get_cookie.js';
@@ -0,0 +1,3 @@
1
+ export { scanFile, type FileScanResult, type DynamicCall } from "./scan_file.js";
2
+ export { matchesNamespacePattern } from "./match_namespace.js";
3
+ export { scanProject, type ScanProjectOptions, type ClientMessagesManifest } from "./scan_project.js";
@@ -0,0 +1,3 @@
1
+ export { scanFile } from "./scan_file.js";
2
+ export { matchesNamespacePattern } from "./match_namespace.js";
3
+ export { scanProject } from "./scan_project.js";
@@ -0,0 +1 @@
1
+ export declare function matchesNamespacePattern(ns: string, pattern: string): boolean;
@@ -0,0 +1,3 @@
1
+ export function matchesNamespacePattern(ns, pattern) {
2
+ return pattern.endsWith("*") ? ns.startsWith(pattern.slice(0, -1)) : ns === pattern;
3
+ }
@@ -0,0 +1,16 @@
1
+ export interface DynamicCall {
2
+ file: string;
3
+ line: number;
4
+ text: string;
5
+ prop?: {
6
+ component: string;
7
+ name: string;
8
+ };
9
+ }
10
+ export interface FileScanResult {
11
+ namespaces: string[];
12
+ dynamicCalls: DynamicCall[];
13
+ usesRoot: boolean;
14
+ }
15
+ export declare function findJsxPropValues(file: string, code: string, component: string, prop: string): string[] | null;
16
+ export declare function scanFile(file: string, code: string): FileScanResult;