@comvi/next 0.1.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 (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +256 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +23 -0
  4. package/dist/client/I18nProvider.cjs +101 -0
  5. package/dist/client/I18nProvider.d.ts +84 -0
  6. package/dist/client/I18nProvider.d.ts.map +1 -0
  7. package/dist/client/I18nProvider.js +99 -0
  8. package/dist/client/index.d.ts +5 -0
  9. package/dist/client/index.d.ts.map +1 -0
  10. package/dist/client.cjs +31 -0
  11. package/dist/client.d.ts +5 -0
  12. package/dist/client.d.ts.map +1 -0
  13. package/dist/client.js +5 -0
  14. package/dist/createNextI18n.cjs +153 -0
  15. package/dist/createNextI18n.d.ts +183 -0
  16. package/dist/createNextI18n.d.ts.map +1 -0
  17. package/dist/createNextI18n.js +152 -0
  18. package/dist/index.cjs +17 -0
  19. package/dist/index.d.ts +9 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +3 -0
  22. package/dist/middleware/createMiddleware.cjs +185 -0
  23. package/dist/middleware/createMiddleware.d.ts +38 -0
  24. package/dist/middleware/createMiddleware.d.ts.map +1 -0
  25. package/dist/middleware/createMiddleware.js +184 -0
  26. package/dist/middleware/types.d.ts +87 -0
  27. package/dist/middleware/types.d.ts.map +1 -0
  28. package/dist/middleware.cjs +3 -0
  29. package/dist/middleware.d.ts +3 -0
  30. package/dist/middleware.d.ts.map +1 -0
  31. package/dist/middleware.js +2 -0
  32. package/dist/navigation.cjs +8 -0
  33. package/dist/navigation.d.ts +5 -0
  34. package/dist/navigation.d.ts.map +1 -0
  35. package/dist/navigation.js +5 -0
  36. package/dist/routing/Link.cjs +42 -0
  37. package/dist/routing/Link.d.ts +25 -0
  38. package/dist/routing/Link.d.ts.map +1 -0
  39. package/dist/routing/Link.js +39 -0
  40. package/dist/routing/context.cjs +21 -0
  41. package/dist/routing/context.d.ts +9 -0
  42. package/dist/routing/context.d.ts.map +1 -0
  43. package/dist/routing/context.js +18 -0
  44. package/dist/routing/defineRouting.cjs +141 -0
  45. package/dist/routing/defineRouting.d.ts +123 -0
  46. package/dist/routing/defineRouting.d.ts.map +1 -0
  47. package/dist/routing/defineRouting.js +139 -0
  48. package/dist/routing/hooks.cjs +104 -0
  49. package/dist/routing/hooks.d.ts +66 -0
  50. package/dist/routing/hooks.d.ts.map +1 -0
  51. package/dist/routing/hooks.js +102 -0
  52. package/dist/routing/types.d.ts +35 -0
  53. package/dist/routing/types.d.ts.map +1 -0
  54. package/dist/routing/utils.cjs +94 -0
  55. package/dist/routing/utils.d.ts +8 -0
  56. package/dist/routing/utils.d.ts.map +1 -0
  57. package/dist/routing/utils.js +91 -0
  58. package/dist/routing.cjs +5 -0
  59. package/dist/routing.d.ts +4 -0
  60. package/dist/routing.d.ts.map +1 -0
  61. package/dist/routing.js +2 -0
  62. package/dist/server/cache.cjs +69 -0
  63. package/dist/server/cache.d.ts +42 -0
  64. package/dist/server/cache.d.ts.map +1 -0
  65. package/dist/server/cache.js +66 -0
  66. package/dist/server/ensureInitialized.cjs +19 -0
  67. package/dist/server/ensureInitialized.d.ts +7 -0
  68. package/dist/server/ensureInitialized.d.ts.map +1 -0
  69. package/dist/server/ensureInitialized.js +19 -0
  70. package/dist/server/getI18n.cjs +115 -0
  71. package/dist/server/getI18n.d.ts +61 -0
  72. package/dist/server/getI18n.d.ts.map +1 -0
  73. package/dist/server/getI18n.js +114 -0
  74. package/dist/server/getLocale.cjs +37 -0
  75. package/dist/server/getLocale.d.ts +22 -0
  76. package/dist/server/getLocale.d.ts.map +1 -0
  77. package/dist/server/getLocale.js +36 -0
  78. package/dist/server/loadTranslations.cjs +54 -0
  79. package/dist/server/loadTranslations.d.ts +34 -0
  80. package/dist/server/loadTranslations.d.ts.map +1 -0
  81. package/dist/server/loadTranslations.js +54 -0
  82. package/dist/server/setRequestLocale.cjs +31 -0
  83. package/dist/server/setRequestLocale.d.ts +26 -0
  84. package/dist/server/setRequestLocale.d.ts.map +1 -0
  85. package/dist/server/setRequestLocale.js +31 -0
  86. package/dist/server/types.d.ts +43 -0
  87. package/dist/server/types.d.ts.map +1 -0
  88. package/dist/server.cjs +11 -0
  89. package/dist/server.d.ts +8 -0
  90. package/dist/server.d.ts.map +1 -0
  91. package/dist/server.js +6 -0
  92. package/package.json +111 -0
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
3
+ const require_defineRouting = require("./defineRouting.cjs");
4
+ let react = require("react");
5
+ react = require_runtime.__toESM(react);
6
+ let react_jsx_runtime = require("react/jsx-runtime");
7
+ //#region src/routing/context.tsx
8
+ var RoutingContext = (0, react.createContext)(null);
9
+ function RoutingProvider({ routing, children }) {
10
+ const value = (0, react.useMemo)(() => require_defineRouting.defineRouting(routing), [routing]);
11
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RoutingContext.Provider, {
12
+ value,
13
+ children
14
+ });
15
+ }
16
+ function useRoutingConfig() {
17
+ return (0, react.useContext)(RoutingContext);
18
+ }
19
+ //#endregion
20
+ exports.RoutingProvider = RoutingProvider;
21
+ exports.useRoutingConfig = useRoutingConfig;
@@ -0,0 +1,9 @@
1
+ import { default as React } from 'react';
2
+ import { RoutingConfig } from './types';
3
+ export interface RoutingProviderProps {
4
+ routing: RoutingConfig;
5
+ children: React.ReactNode;
6
+ }
7
+ export declare function RoutingProvider({ routing, children }: RoutingProviderProps): import("react/jsx-runtime").JSX.Element;
8
+ export declare function useRoutingConfig(): Required<RoutingConfig> | null;
9
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/routing/context.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,eAAe,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,oBAAoB,2CAG1E;AAED,wBAAgB,gBAAgB,IAAI,QAAQ,CAAC,aAAa,CAAC,GAAG,IAAI,CAEjE"}
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { defineRouting } from "./defineRouting.js";
3
+ import { createContext, useContext, useMemo } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/routing/context.tsx
6
+ var RoutingContext = createContext(null);
7
+ function RoutingProvider({ routing, children }) {
8
+ const value = useMemo(() => defineRouting(routing), [routing]);
9
+ return /* @__PURE__ */ jsx(RoutingContext.Provider, {
10
+ value,
11
+ children
12
+ });
13
+ }
14
+ function useRoutingConfig() {
15
+ return useContext(RoutingContext);
16
+ }
17
+ //#endregion
18
+ export { RoutingProvider, useRoutingConfig };
@@ -0,0 +1,141 @@
1
+ //#region src/routing/defineRouting.ts
2
+ /**
3
+ * Define routing configuration for your app
4
+ *
5
+ * This configuration is used by both the middleware and navigation components
6
+ * to handle localized routing.
7
+ *
8
+ * @param config - Routing configuration
9
+ * @returns The same configuration with defaults applied
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // i18n/routing.ts
14
+ * import { defineRouting } from '@comvi/next/routing';
15
+ *
16
+ * export const routing = defineRouting({
17
+ * locales: ['en', 'uk', 'de'],
18
+ * defaultLocale: 'en',
19
+ * localePrefix: 'as-needed',
20
+ * });
21
+ * ```
22
+ */
23
+ function defineRouting(config) {
24
+ return {
25
+ ...config,
26
+ localePrefix: config.localePrefix ?? "as-needed",
27
+ localeCookie: config.localeCookie ?? "NEXT_LOCALE",
28
+ pathnames: config.pathnames ?? {}
29
+ };
30
+ }
31
+ /**
32
+ * Type guard to check if a string is a valid locale
33
+ *
34
+ * Use this in layouts/pages to validate the locale parameter
35
+ * and get proper TypeScript narrowing.
36
+ *
37
+ * @param locales - Array of supported locales
38
+ * @param locale - String to check
39
+ * @returns True if locale is valid
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * import { hasLocale } from '@comvi/next/routing';
44
+ * import { routing } from '@/i18n/routing';
45
+ * import { notFound } from 'next/navigation';
46
+ *
47
+ * export default async function Page({ params }: { params: Promise<{ locale: string }> }) {
48
+ * const { locale } = await params;
49
+ *
50
+ * if (!hasLocale(routing.locales, locale)) {
51
+ * notFound();
52
+ * }
53
+ *
54
+ * // locale is now typed as 'en' | 'uk' | 'de'
55
+ * return <div>Locale: {locale}</div>;
56
+ * }
57
+ * ```
58
+ */
59
+ function hasLocale(locales, locale) {
60
+ return locales.includes(locale);
61
+ }
62
+ /**
63
+ * Creates a getPathname function bound to your routing configuration
64
+ *
65
+ * Use this to construct localized pathnames for sitemaps, hreflang tags,
66
+ * and canonical URLs.
67
+ *
68
+ * @param config - Your routing configuration
69
+ * @returns A getPathname function
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * // i18n/navigation.ts
74
+ * import { createGetPathname } from '@comvi/next/routing';
75
+ * import { routing } from './routing';
76
+ *
77
+ * export const getPathname = createGetPathname(routing);
78
+ * ```
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * // app/sitemap.ts
83
+ * import { getPathname } from '@/i18n/navigation';
84
+ * import { routing } from '@/i18n/routing';
85
+ *
86
+ * export default function sitemap() {
87
+ * const baseUrl = 'https://example.com';
88
+ * const pages = ['/', '/about', '/contact'];
89
+ *
90
+ * return pages.flatMap((page) =>
91
+ * routing.locales.map((locale) => ({
92
+ * url: `${baseUrl}${getPathname({ locale, href: page })}`,
93
+ * lastModified: new Date(),
94
+ * alternates: {
95
+ * languages: Object.fromEntries(
96
+ * routing.locales.map((l) => [
97
+ * l,
98
+ * `${baseUrl}${getPathname({ locale: l, href: page })}`,
99
+ * ])
100
+ * ),
101
+ * },
102
+ * }))
103
+ * );
104
+ * }
105
+ * ```
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * // Generate hreflang tags
110
+ * import { getPathname } from '@/i18n/navigation';
111
+ * import { routing } from '@/i18n/routing';
112
+ *
113
+ * function generateHreflangTags(currentPath: string) {
114
+ * return routing.locales.map((locale) => ({
115
+ * rel: 'alternate',
116
+ * hrefLang: locale,
117
+ * href: `https://example.com${getPathname({ locale, href: currentPath })}`,
118
+ * }));
119
+ * }
120
+ * ```
121
+ */
122
+ function createGetPathname(config) {
123
+ const { locales, defaultLocale, localePrefix, pathnames } = config;
124
+ return function getPathname({ locale, href }) {
125
+ if (!locales.includes(locale)) console.warn(`[getPathname] Unknown locale "${locale}". Expected one of: ${locales.join(", ")}`);
126
+ const localizedPath = pathnames[href]?.[locale] ?? href;
127
+ const normalizedPath = localizedPath.startsWith("/") ? localizedPath : `/${localizedPath}`;
128
+ switch (localePrefix) {
129
+ case "always": return `/${locale}${normalizedPath === "/" ? "" : normalizedPath}`;
130
+ case "as-needed":
131
+ if (locale === defaultLocale) return normalizedPath;
132
+ return `/${locale}${normalizedPath === "/" ? "" : normalizedPath}`;
133
+ case "never": return normalizedPath;
134
+ default: return normalizedPath;
135
+ }
136
+ };
137
+ }
138
+ //#endregion
139
+ exports.createGetPathname = createGetPathname;
140
+ exports.defineRouting = defineRouting;
141
+ exports.hasLocale = hasLocale;
@@ -0,0 +1,123 @@
1
+ import { RoutingConfig } from './types';
2
+ /**
3
+ * Define routing configuration for your app
4
+ *
5
+ * This configuration is used by both the middleware and navigation components
6
+ * to handle localized routing.
7
+ *
8
+ * @param config - Routing configuration
9
+ * @returns The same configuration with defaults applied
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // i18n/routing.ts
14
+ * import { defineRouting } from '@comvi/next/routing';
15
+ *
16
+ * export const routing = defineRouting({
17
+ * locales: ['en', 'uk', 'de'],
18
+ * defaultLocale: 'en',
19
+ * localePrefix: 'as-needed',
20
+ * });
21
+ * ```
22
+ */
23
+ export declare function defineRouting<T extends string>(config: RoutingConfig<T>): Required<RoutingConfig<T>>;
24
+ /**
25
+ * Type guard to check if a string is a valid locale
26
+ *
27
+ * Use this in layouts/pages to validate the locale parameter
28
+ * and get proper TypeScript narrowing.
29
+ *
30
+ * @param locales - Array of supported locales
31
+ * @param locale - String to check
32
+ * @returns True if locale is valid
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * import { hasLocale } from '@comvi/next/routing';
37
+ * import { routing } from '@/i18n/routing';
38
+ * import { notFound } from 'next/navigation';
39
+ *
40
+ * export default async function Page({ params }: { params: Promise<{ locale: string }> }) {
41
+ * const { locale } = await params;
42
+ *
43
+ * if (!hasLocale(routing.locales, locale)) {
44
+ * notFound();
45
+ * }
46
+ *
47
+ * // locale is now typed as 'en' | 'uk' | 'de'
48
+ * return <div>Locale: {locale}</div>;
49
+ * }
50
+ * ```
51
+ */
52
+ export declare function hasLocale<T extends string>(locales: readonly T[], locale: string): locale is T;
53
+ /**
54
+ * Options for getPathname function
55
+ */
56
+ export interface GetPathnameOptions {
57
+ /** Target locale */
58
+ locale: string;
59
+ /** The pathname (without locale prefix) */
60
+ href: string;
61
+ }
62
+ /**
63
+ * Creates a getPathname function bound to your routing configuration
64
+ *
65
+ * Use this to construct localized pathnames for sitemaps, hreflang tags,
66
+ * and canonical URLs.
67
+ *
68
+ * @param config - Your routing configuration
69
+ * @returns A getPathname function
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * // i18n/navigation.ts
74
+ * import { createGetPathname } from '@comvi/next/routing';
75
+ * import { routing } from './routing';
76
+ *
77
+ * export const getPathname = createGetPathname(routing);
78
+ * ```
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * // app/sitemap.ts
83
+ * import { getPathname } from '@/i18n/navigation';
84
+ * import { routing } from '@/i18n/routing';
85
+ *
86
+ * export default function sitemap() {
87
+ * const baseUrl = 'https://example.com';
88
+ * const pages = ['/', '/about', '/contact'];
89
+ *
90
+ * return pages.flatMap((page) =>
91
+ * routing.locales.map((locale) => ({
92
+ * url: `${baseUrl}${getPathname({ locale, href: page })}`,
93
+ * lastModified: new Date(),
94
+ * alternates: {
95
+ * languages: Object.fromEntries(
96
+ * routing.locales.map((l) => [
97
+ * l,
98
+ * `${baseUrl}${getPathname({ locale: l, href: page })}`,
99
+ * ])
100
+ * ),
101
+ * },
102
+ * }))
103
+ * );
104
+ * }
105
+ * ```
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * // Generate hreflang tags
110
+ * import { getPathname } from '@/i18n/navigation';
111
+ * import { routing } from '@/i18n/routing';
112
+ *
113
+ * function generateHreflangTags(currentPath: string) {
114
+ * return routing.locales.map((locale) => ({
115
+ * rel: 'alternate',
116
+ * hrefLang: locale,
117
+ * href: `https://example.com${getPathname({ locale, href: currentPath })}`,
118
+ * }));
119
+ * }
120
+ * ```
121
+ */
122
+ export declare function createGetPathname<T extends string>(config: Required<RoutingConfig<T>>): (options: GetPathnameOptions) => string;
123
+ //# sourceMappingURL=defineRouting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defineRouting.d.ts","sourceRoot":"","sources":["../../src/routing/defineRouting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAC5C,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GACvB,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAO5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC,CAE9F;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAChD,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GACjC,CAAC,OAAO,EAAE,kBAAkB,KAAK,MAAM,CAsCzC"}
@@ -0,0 +1,139 @@
1
+ //#region src/routing/defineRouting.ts
2
+ /**
3
+ * Define routing configuration for your app
4
+ *
5
+ * This configuration is used by both the middleware and navigation components
6
+ * to handle localized routing.
7
+ *
8
+ * @param config - Routing configuration
9
+ * @returns The same configuration with defaults applied
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // i18n/routing.ts
14
+ * import { defineRouting } from '@comvi/next/routing';
15
+ *
16
+ * export const routing = defineRouting({
17
+ * locales: ['en', 'uk', 'de'],
18
+ * defaultLocale: 'en',
19
+ * localePrefix: 'as-needed',
20
+ * });
21
+ * ```
22
+ */
23
+ function defineRouting(config) {
24
+ return {
25
+ ...config,
26
+ localePrefix: config.localePrefix ?? "as-needed",
27
+ localeCookie: config.localeCookie ?? "NEXT_LOCALE",
28
+ pathnames: config.pathnames ?? {}
29
+ };
30
+ }
31
+ /**
32
+ * Type guard to check if a string is a valid locale
33
+ *
34
+ * Use this in layouts/pages to validate the locale parameter
35
+ * and get proper TypeScript narrowing.
36
+ *
37
+ * @param locales - Array of supported locales
38
+ * @param locale - String to check
39
+ * @returns True if locale is valid
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * import { hasLocale } from '@comvi/next/routing';
44
+ * import { routing } from '@/i18n/routing';
45
+ * import { notFound } from 'next/navigation';
46
+ *
47
+ * export default async function Page({ params }: { params: Promise<{ locale: string }> }) {
48
+ * const { locale } = await params;
49
+ *
50
+ * if (!hasLocale(routing.locales, locale)) {
51
+ * notFound();
52
+ * }
53
+ *
54
+ * // locale is now typed as 'en' | 'uk' | 'de'
55
+ * return <div>Locale: {locale}</div>;
56
+ * }
57
+ * ```
58
+ */
59
+ function hasLocale(locales, locale) {
60
+ return locales.includes(locale);
61
+ }
62
+ /**
63
+ * Creates a getPathname function bound to your routing configuration
64
+ *
65
+ * Use this to construct localized pathnames for sitemaps, hreflang tags,
66
+ * and canonical URLs.
67
+ *
68
+ * @param config - Your routing configuration
69
+ * @returns A getPathname function
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * // i18n/navigation.ts
74
+ * import { createGetPathname } from '@comvi/next/routing';
75
+ * import { routing } from './routing';
76
+ *
77
+ * export const getPathname = createGetPathname(routing);
78
+ * ```
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * // app/sitemap.ts
83
+ * import { getPathname } from '@/i18n/navigation';
84
+ * import { routing } from '@/i18n/routing';
85
+ *
86
+ * export default function sitemap() {
87
+ * const baseUrl = 'https://example.com';
88
+ * const pages = ['/', '/about', '/contact'];
89
+ *
90
+ * return pages.flatMap((page) =>
91
+ * routing.locales.map((locale) => ({
92
+ * url: `${baseUrl}${getPathname({ locale, href: page })}`,
93
+ * lastModified: new Date(),
94
+ * alternates: {
95
+ * languages: Object.fromEntries(
96
+ * routing.locales.map((l) => [
97
+ * l,
98
+ * `${baseUrl}${getPathname({ locale: l, href: page })}`,
99
+ * ])
100
+ * ),
101
+ * },
102
+ * }))
103
+ * );
104
+ * }
105
+ * ```
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * // Generate hreflang tags
110
+ * import { getPathname } from '@/i18n/navigation';
111
+ * import { routing } from '@/i18n/routing';
112
+ *
113
+ * function generateHreflangTags(currentPath: string) {
114
+ * return routing.locales.map((locale) => ({
115
+ * rel: 'alternate',
116
+ * hrefLang: locale,
117
+ * href: `https://example.com${getPathname({ locale, href: currentPath })}`,
118
+ * }));
119
+ * }
120
+ * ```
121
+ */
122
+ function createGetPathname(config) {
123
+ const { locales, defaultLocale, localePrefix, pathnames } = config;
124
+ return function getPathname({ locale, href }) {
125
+ if (!locales.includes(locale)) console.warn(`[getPathname] Unknown locale "${locale}". Expected one of: ${locales.join(", ")}`);
126
+ const localizedPath = pathnames[href]?.[locale] ?? href;
127
+ const normalizedPath = localizedPath.startsWith("/") ? localizedPath : `/${localizedPath}`;
128
+ switch (localePrefix) {
129
+ case "always": return `/${locale}${normalizedPath === "/" ? "" : normalizedPath}`;
130
+ case "as-needed":
131
+ if (locale === defaultLocale) return normalizedPath;
132
+ return `/${locale}${normalizedPath === "/" ? "" : normalizedPath}`;
133
+ case "never": return normalizedPath;
134
+ default: return normalizedPath;
135
+ }
136
+ };
137
+ }
138
+ //#endregion
139
+ export { createGetPathname, defineRouting, hasLocale };
@@ -0,0 +1,104 @@
1
+ "use client";
2
+ "use client";
3
+ require("../_virtual/_rolldown/runtime.cjs");
4
+ const require_context = require("./context.cjs");
5
+ const require_utils = require("./utils.cjs");
6
+ let react = require("react");
7
+ let _comvi_react = require("@comvi/react");
8
+ let next_navigation = require("next/navigation");
9
+ //#region src/routing/hooks.ts
10
+ /**
11
+ * Get pathname without locale prefix
12
+ *
13
+ * This hook returns the current pathname with the locale prefix removed,
14
+ * making it easier to work with routes in a locale-agnostic way.
15
+ *
16
+ * @returns Pathname without locale prefix
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * import { usePathname } from '@comvi/next/navigation';
21
+ *
22
+ * function MyComponent() {
23
+ * const pathname = usePathname();
24
+ * // If URL is /en/about, pathname is /about
25
+ * return <p>Current page: {pathname}</p>;
26
+ * }
27
+ * ```
28
+ */
29
+ function usePathname() {
30
+ const pathname = (0, next_navigation.usePathname)() ?? "/";
31
+ const routing = require_context.useRoutingConfig();
32
+ const { locale } = (0, _comvi_react.useI18n)();
33
+ if (routing) return require_utils.getCanonicalPathname(require_utils.stripLocalePrefix(pathname, routing.locales), routing, locale);
34
+ if (pathname.startsWith(`/${locale}/`)) return pathname.slice(locale.length + 1);
35
+ if (pathname === `/${locale}`) return "/";
36
+ return pathname;
37
+ }
38
+ /**
39
+ * Localized router with automatic locale prefixing
40
+ *
41
+ * This hook wraps Next.js useRouter and automatically adds locale
42
+ * prefixes to navigation methods.
43
+ *
44
+ * @returns Localized router object
45
+ *
46
+ * @example
47
+ * ```tsx
48
+ * import { useLocalizedRouter } from '@comvi/next/navigation';
49
+ *
50
+ * function MyComponent() {
51
+ * const router = useLocalizedRouter();
52
+ *
53
+ * const handleClick = () => {
54
+ * router.push('/about'); // Navigates to /en/about (or current locale)
55
+ * };
56
+ *
57
+ * const handleGerman = () => {
58
+ * router.push('/about', 'de'); // Navigates to /de/about
59
+ * };
60
+ *
61
+ * return <button onClick={handleClick}>Go to About</button>;
62
+ * }
63
+ * ```
64
+ */
65
+ function useLocalizedRouter() {
66
+ const router = (0, next_navigation.useRouter)();
67
+ const { locale } = (0, _comvi_react.useI18n)();
68
+ const routing = require_context.useRoutingConfig();
69
+ const push = (0, react.useCallback)((href, targetLocale) => {
70
+ const localizedHref = require_utils.localizeHref(href, targetLocale ?? locale, routing ?? void 0);
71
+ router.push(localizedHref);
72
+ }, [
73
+ router,
74
+ locale,
75
+ routing
76
+ ]);
77
+ const replace = (0, react.useCallback)((href, targetLocale) => {
78
+ const localizedHref = require_utils.localizeHref(href, targetLocale ?? locale, routing ?? void 0);
79
+ router.replace(localizedHref);
80
+ }, [
81
+ router,
82
+ locale,
83
+ routing
84
+ ]);
85
+ const prefetch = (0, react.useCallback)((href, targetLocale) => {
86
+ const localizedHref = require_utils.localizeHref(href, targetLocale ?? locale, routing ?? void 0);
87
+ router.prefetch(localizedHref);
88
+ }, [
89
+ router,
90
+ locale,
91
+ routing
92
+ ]);
93
+ return {
94
+ push,
95
+ replace,
96
+ back: router.back,
97
+ forward: router.forward,
98
+ refresh: router.refresh,
99
+ prefetch
100
+ };
101
+ }
102
+ //#endregion
103
+ exports.useLocalizedRouter = useLocalizedRouter;
104
+ exports.usePathname = usePathname;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Get pathname without locale prefix
3
+ *
4
+ * This hook returns the current pathname with the locale prefix removed,
5
+ * making it easier to work with routes in a locale-agnostic way.
6
+ *
7
+ * @returns Pathname without locale prefix
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { usePathname } from '@comvi/next/navigation';
12
+ *
13
+ * function MyComponent() {
14
+ * const pathname = usePathname();
15
+ * // If URL is /en/about, pathname is /about
16
+ * return <p>Current page: {pathname}</p>;
17
+ * }
18
+ * ```
19
+ */
20
+ export declare function usePathname(): string;
21
+ /**
22
+ * Return type for useLocalizedRouter
23
+ */
24
+ export interface LocalizedRouter {
25
+ /** Navigate to a localized path */
26
+ push: (href: string, locale?: string) => void;
27
+ /** Replace current history entry with a localized path */
28
+ replace: (href: string, locale?: string) => void;
29
+ /** Navigate back */
30
+ back: () => void;
31
+ /** Navigate forward */
32
+ forward: () => void;
33
+ /** Refresh the current page */
34
+ refresh: () => void;
35
+ /** Prefetch a localized path */
36
+ prefetch: (href: string, locale?: string) => void;
37
+ }
38
+ /**
39
+ * Localized router with automatic locale prefixing
40
+ *
41
+ * This hook wraps Next.js useRouter and automatically adds locale
42
+ * prefixes to navigation methods.
43
+ *
44
+ * @returns Localized router object
45
+ *
46
+ * @example
47
+ * ```tsx
48
+ * import { useLocalizedRouter } from '@comvi/next/navigation';
49
+ *
50
+ * function MyComponent() {
51
+ * const router = useLocalizedRouter();
52
+ *
53
+ * const handleClick = () => {
54
+ * router.push('/about'); // Navigates to /en/about (or current locale)
55
+ * };
56
+ *
57
+ * const handleGerman = () => {
58
+ * router.push('/about', 'de'); // Navigates to /de/about
59
+ * };
60
+ *
61
+ * return <button onClick={handleClick}>Go to About</button>;
62
+ * }
63
+ * ```
64
+ */
65
+ export declare function useLocalizedRouter(): LocalizedRouter;
66
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/routing/hooks.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAkBpC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,0DAA0D;IAC1D,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,oBAAoB;IACpB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,uBAAuB;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gCAAgC;IAChC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACnD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAwCpD"}