next-intl 4.0.0-beta-db95243 → 4.0.0-beta-8f37883

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.
@@ -16,7 +16,7 @@ function createNavigation(routing) {
16
16
 
17
17
  /** @see https://next-intl-docs.vercel.app/docs/routing/navigation#usepathname */
18
18
  function usePathname$1() {
19
- const pathname = useBasePathname(config.localePrefix);
19
+ const pathname = useBasePathname(config);
20
20
  const locale = useLocale();
21
21
 
22
22
  // @ts-expect-error -- Mirror the behavior from Next.js, where `null` is returned when `usePathname` is used outside of Next, but the types indicate that a string is always returned.
@@ -1,9 +1,9 @@
1
1
  import { usePathname } from 'next/navigation.js';
2
2
  import { useMemo } from 'react';
3
3
  import { useLocale } from 'use-intl';
4
- import { hasPathnamePrefixed, unprefixPathname, getLocalePrefix } from '../../shared/utils.js';
4
+ import { hasPathnamePrefixed, unprefixPathname, getLocalePrefix, getLocaleAsPrefix } from '../../shared/utils.js';
5
5
 
6
- function useBasePathname(localePrefix) {
6
+ function useBasePathname(config) {
7
7
  // The types aren't entirely correct here. Outside of Next.js
8
8
  // `useParams` can be called, but the return type is `null`.
9
9
 
@@ -17,11 +17,20 @@ function useBasePathname(localePrefix) {
17
17
  const locale = useLocale();
18
18
  return useMemo(() => {
19
19
  if (!pathname) return pathname;
20
- const prefix = getLocalePrefix(locale, localePrefix);
20
+ let unlocalizedPathname = pathname;
21
+ const prefix = getLocalePrefix(locale, config.localePrefix);
21
22
  const isPathnamePrefixed = hasPathnamePrefixed(prefix, pathname);
22
- const unlocalizedPathname = isPathnamePrefixed ? unprefixPathname(pathname, prefix) : pathname;
23
+ if (isPathnamePrefixed) {
24
+ unlocalizedPathname = unprefixPathname(pathname, prefix);
25
+ } else if (config.localePrefix.mode === 'as-needed' && config.localePrefix.prefixes) {
26
+ // Workaround for https://github.com/vercel/next.js/issues/73085
27
+ const localeAsPrefix = getLocaleAsPrefix(locale);
28
+ if (hasPathnamePrefixed(localeAsPrefix, pathname)) {
29
+ unlocalizedPathname = unprefixPathname(pathname, localeAsPrefix);
30
+ }
31
+ }
23
32
  return unlocalizedPathname;
24
- }, [locale, localePrefix, pathname]);
33
+ }, [config.localePrefix, locale, pathname]);
25
34
  }
26
35
 
27
36
  export { useBasePathname as default };
@@ -61,7 +61,10 @@ function getLocalePrefix(locale, localePrefix) {
61
61
  return localePrefix.mode !== 'never' && localePrefix.prefixes?.[locale] ||
62
62
  // We return a prefix even if `mode: 'never'`. It's up to the consumer
63
63
  // to decide to use it or not.
64
- '/' + locale;
64
+ getLocaleAsPrefix(locale);
65
+ }
66
+ function getLocaleAsPrefix(locale) {
67
+ return '/' + locale;
65
68
  }
66
69
  function templateToRegex(template) {
67
70
  const regexPattern = template
@@ -120,4 +123,4 @@ function getSortedPathnames(pathnames) {
120
123
  return pathnames.sort(comparePathnamePairs);
121
124
  }
122
125
 
123
- export { getLocalePrefix, getSortedPathnames, hasPathnamePrefixed, isLocalizableHref, matchesPathname, normalizeTrailingSlash, prefixPathname, templateToRegex, unprefixPathname };
126
+ export { getLocaleAsPrefix, getLocalePrefix, getSortedPathnames, hasPathnamePrefixed, isLocalizableHref, matchesPathname, normalizeTrailingSlash, prefixPathname, templateToRegex, unprefixPathname };
@@ -1 +1 @@
1
- import{useRouter as e,usePathname as t}from"next/navigation.js";import{useMemo as o}from"react";import{useLocale as n}from"use-intl";import r from"../shared/createSharedNavigationFns.js";import a from"../shared/syncLocaleCookie.js";import{getRoute as s}from"../shared/utils.js";import i from"./useBasePathname.js";function c(c){const{Link:m,config:u,getPathname:f,...h}=r(n,c);return{...h,Link:m,usePathname:function(){const e=i(u.localePrefix),t=n();return o((()=>e&&u.pathnames?s(t,e,u.pathnames):e),[t,e])},useRouter:function(){const r=e(),s=n(),i=t();return o((()=>{function e(e){return function(t,o){const{locale:n,...r}=o||{},c=[f({href:t,locale:n||s,domain:window.location.host})];Object.keys(r).length>0&&c.push(r),e(...c),a(u.localeCookie,i,s,n)}}return{...r,push:e(r.push),replace:e(r.replace),prefetch:e(r.prefetch)}}),[s,i,r])},getPathname:f}}export{c as default};
1
+ import{useRouter as e,usePathname as t}from"next/navigation.js";import{useMemo as o}from"react";import{useLocale as n}from"use-intl";import r from"../shared/createSharedNavigationFns.js";import a from"../shared/syncLocaleCookie.js";import{getRoute as s}from"../shared/utils.js";import i from"./useBasePathname.js";function c(c){const{Link:m,config:u,getPathname:h,...f}=r(n,c);return{...f,Link:m,usePathname:function(){const e=i(u),t=n();return o((()=>e&&u.pathnames?s(t,e,u.pathnames):e),[t,e])},useRouter:function(){const r=e(),s=n(),i=t();return o((()=>{function e(e){return function(t,o){const{locale:n,...r}=o||{},c=[h({href:t,locale:n||s,domain:window.location.host})];Object.keys(r).length>0&&c.push(r),e(...c),a(u.localeCookie,i,s,n)}}return{...r,push:e(r.push),replace:e(r.replace),prefetch:e(r.prefetch)}}),[s,i,r])},getPathname:h}}export{c as default};
@@ -1 +1 @@
1
- import{usePathname as r}from"next/navigation.js";import{useMemo as t}from"react";import{useLocale as o}from"use-intl";import{hasPathnamePrefixed as n,unprefixPathname as i,getLocalePrefix as e}from"../../shared/utils.js";function m(m){const s=r(),f=o();return t((()=>{if(!s)return s;const r=e(f,m);return n(r,s)?i(s,r):s}),[f,m,s])}export{m as default};
1
+ import{usePathname as e}from"next/navigation.js";import{useMemo as r}from"react";import{useLocale as o}from"use-intl";import{hasPathnamePrefixed as t,unprefixPathname as i,getLocalePrefix as f,getLocaleAsPrefix as l}from"../../shared/utils.js";function n(n){const s=e(),a=o();return r((()=>{if(!s)return s;let e=s;const r=f(a,n.localePrefix);if(t(r,s))e=i(s,r);else if("as-needed"===n.localePrefix.mode&&n.localePrefix.prefixes){const r=l(a);t(r,s)&&(e=i(s,r))}return e}),[n.localePrefix,a,s])}export{n as default};
@@ -1 +1 @@
1
- function t(t){return function(t){return"object"==typeof t?null==t.host&&null==t.hostname:!/^[a-z]+:/i.test(t)}(t)&&!function(t){const n="object"==typeof t?t.pathname:t;return null!=n&&!n.startsWith("/")}(t)}function n(t,n){return t.replace(new RegExp(`^${n}`),"")||"/"}function e(t,n){let e=t;return/^\/(\?.*)?$/.test(n)&&(n=n.slice(1)),e+=n,e}function r(t,n){return n===t||n.startsWith(`${t}/`)}function u(t){const n=function(){try{return"true"===process.env._next_intl_trailing_slash}catch{return!1}}();if("/"!==t){const e=t.endsWith("/");n&&!e?t+="/":!n&&e&&(t=t.slice(0,-1))}return t}function i(t,n){const e=u(t),r=u(n);return o(e).test(r)}function c(t,n){return"never"!==n.mode&&n.prefixes?.[t]||"/"+t}function o(t){const n=t.replace(/\[\[(\.\.\.[^\]]+)\]\]/g,"?(.*)").replace(/\[(\.\.\.[^\]]+)\]/g,"(.+)").replace(/\[([^\]]+)\]/g,"([^/]+)");return new RegExp(`^${n}$`)}function f(t){return t.includes("[[...")}function s(t){return t.includes("[...")}function l(t){return t.includes("[")}function a(t,n){const e=t.split("/"),r=n.split("/"),u=Math.max(e.length,r.length);for(let t=0;t<u;t++){const n=e[t],u=r[t];if(!n&&u)return-1;if(n&&!u)return 1;if(n||u){if(!l(n)&&l(u))return-1;if(l(n)&&!l(u))return 1;if(!s(n)&&s(u))return-1;if(s(n)&&!s(u))return 1;if(!f(n)&&f(u))return-1;if(f(n)&&!f(u))return 1}}return 0}function p(t){return t.sort(a)}export{c as getLocalePrefix,p as getSortedPathnames,r as hasPathnamePrefixed,t as isLocalizableHref,i as matchesPathname,u as normalizeTrailingSlash,e as prefixPathname,o as templateToRegex,n as unprefixPathname};
1
+ function n(n){return function(n){return"object"==typeof n?null==n.host&&null==n.hostname:!/^[a-z]+:/i.test(n)}(n)&&!function(n){const t="object"==typeof n?n.pathname:n;return null!=t&&!t.startsWith("/")}(n)}function t(n,t){return n.replace(new RegExp(`^${t}`),"")||"/"}function e(n,t){let e=n;return/^\/(\?.*)?$/.test(t)&&(t=t.slice(1)),e+=t,e}function r(n,t){return t===n||t.startsWith(`${n}/`)}function u(n){const t=function(){try{return"true"===process.env._next_intl_trailing_slash}catch{return!1}}();if("/"!==n){const e=n.endsWith("/");t&&!e?n+="/":!t&&e&&(n=n.slice(0,-1))}return n}function i(n,t){const e=u(n),r=u(t);return f(e).test(r)}function c(n,t){return"never"!==t.mode&&t.prefixes?.[n]||o(n)}function o(n){return"/"+n}function f(n){const t=n.replace(/\[\[(\.\.\.[^\]]+)\]\]/g,"?(.*)").replace(/\[(\.\.\.[^\]]+)\]/g,"(.+)").replace(/\[([^\]]+)\]/g,"([^/]+)");return new RegExp(`^${t}$`)}function s(n){return n.includes("[[...")}function l(n){return n.includes("[...")}function a(n){return n.includes("[")}function p(n,t){const e=n.split("/"),r=t.split("/"),u=Math.max(e.length,r.length);for(let n=0;n<u;n++){const t=e[n],u=r[n];if(!t&&u)return-1;if(t&&!u)return 1;if(t||u){if(!a(t)&&a(u))return-1;if(a(t)&&!a(u))return 1;if(!l(t)&&l(u))return-1;if(l(t)&&!l(u))return 1;if(!s(t)&&s(u))return-1;if(s(t)&&!s(u))return 1}}return 0}function h(n){return n.sort(p)}export{o as getLocaleAsPrefix,c as getLocalePrefix,h as getSortedPathnames,r as hasPathnamePrefixed,n as isLocalizableHref,i as matchesPathname,u as normalizeTrailingSlash,e as prefixPathname,f as templateToRegex,t as unprefixPathname};
@@ -1,2 +1,5 @@
1
1
  import type { LocalePrefixConfigVerbose, LocalePrefixMode, Locales } from '../../routing/types.tsx';
2
- export default function useBasePathname<AppLocales extends Locales, AppLocalePrefixMode extends LocalePrefixMode>(localePrefix: LocalePrefixConfigVerbose<AppLocales, AppLocalePrefixMode>): string | null;
2
+ export default function useBasePathname<AppLocales extends Locales, AppLocalePrefixMode extends LocalePrefixMode>(config: {
3
+ localePrefix: LocalePrefixConfigVerbose<AppLocales, AppLocalePrefixMode>;
4
+ defaultLocale?: AppLocales[number];
5
+ }): string | null;
@@ -12,6 +12,7 @@ template: string,
12
12
  /** E.g. `/users/23-jane` */
13
13
  pathname: string): boolean;
14
14
  export declare function getLocalePrefix<AppLocales extends Locales, AppLocalePrefixMode extends LocalePrefixMode>(locale: AppLocales[number], localePrefix: LocalePrefixConfigVerbose<AppLocales, AppLocalePrefixMode>): string;
15
+ export declare function getLocaleAsPrefix(locale: string): string;
15
16
  export declare function templateToRegex(template: string): RegExp;
16
17
  export declare function getSortedPathnames(pathnames: Array<string>): string[];
17
18
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-intl",
3
- "version": "4.0.0-beta-db95243",
3
+ "version": "4.0.0-beta-8f37883",
4
4
  "sideEffects": false,
5
5
  "author": "Jan Amann <jan@amann.work>",
6
6
  "funding": [
@@ -112,7 +112,7 @@
112
112
  "dependencies": {
113
113
  "@formatjs/intl-localematcher": "^0.5.4",
114
114
  "negotiator": "^1.0.0",
115
- "use-intl": "4.0.0-beta-db95243"
115
+ "use-intl": "4.0.0-beta-8f37883"
116
116
  },
117
117
  "peerDependencies": {
118
118
  "next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0",
@@ -124,5 +124,5 @@
124
124
  "optional": true
125
125
  }
126
126
  },
127
- "gitHead": "187381203f4fa54f735057e7984e0d7b897112d0"
127
+ "gitHead": "a9f295bd5e8f3bc25de067dd93d81a1b1bd54977"
128
128
  }