next-intl 4.0.0-beta-ca3fcd5 → 4.0.0-beta-ca68f02

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.
@@ -75,7 +75,7 @@ function getAlternateLinksHeaderValue({
75
75
  // Add x-default entry
76
76
  const shouldAddXDefault =
77
77
  // For domain-based routing there is no reasonable x-default
78
- !routing.domains && (routing.localePrefix.mode !== 'always' || normalizedUrl.pathname === '/');
78
+ !routing.domains || routing.domains.length === 0;
79
79
  if (shouldAddXDefault) {
80
80
  const url = new URL(getLocalizedPathname(normalizedUrl.pathname, routing.defaultLocale), normalizedUrl);
81
81
  links.push(getAlternateEntry(url, 'x-default'));
@@ -2,7 +2,7 @@ import { redirect, permanentRedirect } from 'next/navigation';
2
2
  import { forwardRef } from 'react';
3
3
  import { receiveRoutingConfig } from '../../routing/config.js';
4
4
  import use from '../../shared/use.js';
5
- import { isLocalizableHref } from '../../shared/utils.js';
5
+ import { isLocalizableHref, isPromise } from '../../shared/utils.js';
6
6
  import BaseLink from './BaseLink.js';
7
7
  import { validateReceivedConfig, serializeSearchParams, compileLocalizedPathname, applyPathnamePrefix, normalizeNameOrNameWithParams } from './utils.js';
8
8
  import { jsx } from 'react/jsx-runtime';
@@ -41,7 +41,7 @@ function createSharedNavigationFns(getLocale, routing) {
41
41
  // @ts-expect-error -- This is ok
42
42
  const isLocalizable = isLocalizableHref(href);
43
43
  const localePromiseOrValue = getLocale();
44
- const curLocale = localePromiseOrValue instanceof Promise ? use(localePromiseOrValue) : localePromiseOrValue;
44
+ const curLocale = isPromise(localePromiseOrValue) ? use(localePromiseOrValue) : localePromiseOrValue;
45
45
  const finalPathname = isLocalizable ? getPathname(
46
46
  // @ts-expect-error -- This is ok
47
47
  {
@@ -1,13 +1,14 @@
1
1
  import { headers } from 'next/headers';
2
2
  import { cache } from 'react';
3
3
  import { HEADER_LOCALE_NAME } from '../../shared/constants.js';
4
+ import { isPromise } from '../../shared/utils.js';
4
5
  import { getCachedRequestLocale } from './RequestLocaleCache.js';
5
6
 
6
7
  async function getHeadersImpl() {
7
8
  const promiseOrValue = headers();
8
9
 
9
10
  // Compatibility with Next.js <15
10
- return promiseOrValue instanceof Promise ? await promiseOrValue : promiseOrValue;
11
+ return isPromise(promiseOrValue) ? await promiseOrValue : promiseOrValue;
11
12
  }
12
13
  const getHeaders = cache(getHeadersImpl);
13
14
  async function getLocaleFromHeaderImpl() {
@@ -1,5 +1,6 @@
1
1
  import { cache } from 'react';
2
2
  import { _createIntlFormatters, _createCache, initializeConfig } from 'use-intl/core';
3
+ import { isPromise } from '../../shared/utils.js';
3
4
  import { getRequestLocale } from './RequestLocale.js';
4
5
  import getRuntimeConfig from 'next-intl/config';
5
6
  import validateLocale from './validateLocale.js';
@@ -31,7 +32,7 @@ See also: https://next-intl.dev/docs/usage/configuration#i18n-request
31
32
  }
32
33
  };
33
34
  let result = getConfig(params);
34
- if (result instanceof Promise) {
35
+ if (isPromise(result)) {
35
36
  result = await result;
36
37
  }
37
38
  if (!result.locale) {
@@ -122,5 +122,9 @@ function comparePathnamePairs(a, b) {
122
122
  function getSortedPathnames(pathnames) {
123
123
  return pathnames.sort(comparePathnamePairs);
124
124
  }
125
+ function isPromise(value) {
126
+ // https://github.com/amannn/next-intl/issues/1711
127
+ return typeof value.then === 'function';
128
+ }
125
129
 
126
- export { getLocaleAsPrefix, getLocalePrefix, getSortedPathnames, hasPathnamePrefixed, isLocalizableHref, matchesPathname, normalizeTrailingSlash, prefixPathname, templateToRegex, unprefixPathname };
130
+ export { getLocaleAsPrefix, getLocalePrefix, getSortedPathnames, hasPathnamePrefixed, isLocalizableHref, isPromise, matchesPathname, normalizeTrailingSlash, prefixPathname, templateToRegex, unprefixPathname };
@@ -1 +1 @@
1
- import{normalizeTrailingSlash as e}from"../shared/utils.js";import{getHost as a,getNormalizedPathname as t,getLocalePrefixes as o,isLocaleSupportedOnDomain as n,applyBasePath as l,formatTemplatePathname as r}from"./utils.js";function m({localizedPathnames:m,request:p,resolvedLocale:s,routing:c}){const f=p.nextUrl.clone(),h=a(p.headers);function i(a,t){return a.pathname=e(a.pathname),p.nextUrl.basePath&&((a=new URL(a)).pathname=l(a.pathname,p.nextUrl.basePath)),`<${a.toString()}>; rel="alternate"; hreflang="${t}"`}function u(e,a){return m&&"object"==typeof m?r(e,m[s],m[a]):e}h&&(f.port="",f.host=h),f.protocol=p.headers.get("x-forwarded-proto")??f.protocol,f.pathname=t(f.pathname,c.locales,c.localePrefix);const d=o(c.locales,c.localePrefix,!1).flatMap((([e,a])=>{function t(e){return"/"===e?a:a+e}let o;if(c.domains){return c.domains.filter((a=>n(e,a))).map((a=>(o=new URL(f),o.port="",o.host=a.domain,o.pathname=u(f.pathname,e),e===a.defaultLocale&&"always"!==c.localePrefix.mode||(o.pathname=t(o.pathname)),i(o,e))))}{let a;a=m&&"object"==typeof m?u(f.pathname,e):f.pathname,e===c.defaultLocale&&"always"!==c.localePrefix.mode||(a=t(a)),o=new URL(a,f)}return i(o,e)}));if(!c.domains&&("always"!==c.localePrefix.mode||"/"===f.pathname)){const e=new URL(u(f.pathname,c.defaultLocale),f);d.push(i(e,"x-default"))}return d.join(", ")}export{m as default};
1
+ import{normalizeTrailingSlash as e}from"../shared/utils.js";import{getHost as a,getNormalizedPathname as t,getLocalePrefixes as o,isLocaleSupportedOnDomain as n,applyBasePath as l,formatTemplatePathname as r}from"./utils.js";function s({localizedPathnames:s,request:m,resolvedLocale:p,routing:h}){const i=m.nextUrl.clone(),c=a(m.headers);function f(a,t){return a.pathname=e(a.pathname),m.nextUrl.basePath&&((a=new URL(a)).pathname=l(a.pathname,m.nextUrl.basePath)),`<${a.toString()}>; rel="alternate"; hreflang="${t}"`}function u(e,a){return s&&"object"==typeof s?r(e,s[p],s[a]):e}c&&(i.port="",i.host=c),i.protocol=m.headers.get("x-forwarded-proto")??i.protocol,i.pathname=t(i.pathname,h.locales,h.localePrefix);const d=o(h.locales,h.localePrefix,!1).flatMap((([e,a])=>{function t(e){return"/"===e?a:a+e}let o;if(h.domains){return h.domains.filter((a=>n(e,a))).map((a=>(o=new URL(i),o.port="",o.host=a.domain,o.pathname=u(i.pathname,e),e===a.defaultLocale&&"always"!==h.localePrefix.mode||(o.pathname=t(o.pathname)),f(o,e))))}{let a;a=s&&"object"==typeof s?u(i.pathname,e):i.pathname,e===h.defaultLocale&&"always"!==h.localePrefix.mode||(a=t(a)),o=new URL(a,i)}return f(o,e)}));if(!h.domains||0===h.domains.length){const e=new URL(u(i.pathname,h.defaultLocale),i);d.push(f(e,"x-default"))}return d.join(", ")}export{s as default};
@@ -1 +1 @@
1
- import{redirect as e,permanentRedirect as o}from"next/navigation";import{forwardRef as a}from"react";import{receiveRoutingConfig as t}from"../../routing/config.js";import n from"../../shared/use.js";import{isLocalizableHref as r}from"../../shared/utils.js";import i from"./BaseLink.js";import{serializeSearchParams as m,compileLocalizedPathname as l,applyPathnamePrefix as c,normalizeNameOrNameWithParams as f}from"./utils.js";import{jsx as s}from"react/jsx-runtime";function u(u,p){const d=t(p||{}),h=d.pathnames,j="as-needed"===d.localePrefix.mode&&d.domains||void 0;function g({href:e,locale:o,...a},t){let m,l;"object"==typeof e?(m=e.pathname,l=e.params):m=e;const c=r(e),f=u(),p=f instanceof Promise?n(f):f,g=c?x({locale:o||p,href:null==h?m:{pathname:m,params:l}},null!=o||j||void 0):m;return s(i,{ref:t,defaultLocale:d.defaultLocale,href:"object"==typeof e?{...e,pathname:g}:g,locale:o,localeCookie:d.localeCookie,unprefixed:j&&c?{domains:d.domains.reduce(((e,o)=>(e[o.domain]=o.defaultLocale,e)),{}),pathname:x({locale:p,href:null==h?m:{pathname:m,params:l}},!1)}:void 0,...a})}const v=a(g);function x(e,o){const{href:a,locale:t}=e;let n;return null==h?"object"==typeof a?(n=a.pathname,a.query&&(n+=m(a.query))):n=a:n=l({locale:t,...f(a),pathnames:d.pathnames}),c(n,t,d,e.domain,o)}function y(e){return function(o,...a){return e(x(o,o.domain?void 0:j),...a)}}const L=y(e),k=y(o);return{config:d,Link:v,redirect:L,permanentRedirect:k,getPathname:x}}export{u as default};
1
+ import{redirect as e,permanentRedirect as o}from"next/navigation";import{forwardRef as a}from"react";import{receiveRoutingConfig as t}from"../../routing/config.js";import n from"../../shared/use.js";import{isLocalizableHref as r,isPromise as i}from"../../shared/utils.js";import m from"./BaseLink.js";import{serializeSearchParams as l,compileLocalizedPathname as c,applyPathnamePrefix as f,normalizeNameOrNameWithParams as s}from"./utils.js";import{jsx as u}from"react/jsx-runtime";function p(p,d){const h=t(d||{}),j=h.pathnames,g="as-needed"===h.localePrefix.mode&&h.domains||void 0;function v({href:e,locale:o,...a},t){let l,c;"object"==typeof e?(l=e.pathname,c=e.params):l=e;const f=r(e),s=p(),d=i(s)?n(s):s,v=f?y({locale:o||d,href:null==j?l:{pathname:l,params:c}},null!=o||g||void 0):l;return u(m,{ref:t,defaultLocale:h.defaultLocale,href:"object"==typeof e?{...e,pathname:v}:v,locale:o,localeCookie:h.localeCookie,unprefixed:g&&f?{domains:h.domains.reduce(((e,o)=>(e[o.domain]=o.defaultLocale,e)),{}),pathname:y({locale:d,href:null==j?l:{pathname:l,params:c}},!1)}:void 0,...a})}const x=a(v);function y(e,o){const{href:a,locale:t}=e;let n;return null==j?"object"==typeof a?(n=a.pathname,a.query&&(n+=l(a.query))):n=a:n=c({locale:t,...s(a),pathnames:h.pathnames}),f(n,t,h,e.domain,o)}function L(e){return function(o,...a){return e(y(o,o.domain?void 0:g),...a)}}const k=L(e),b=L(o);return{config:h,Link:x,redirect:k,permanentRedirect:b,getPathname:y}}export{p as default};
@@ -1 +1 @@
1
- import{headers as t}from"next/headers";import{cache as e}from"react";import{HEADER_LOCALE_NAME as n}from"../../shared/constants.js";import{getCachedRequestLocale as r}from"./RequestLocaleCache.js";const o=e((async function(){const e=t();return e instanceof Promise?await e:e}));const i=e((async function(){let t;try{t=(await o()).get(n)||void 0}catch(t){if(t instanceof Error&&"DYNAMIC_SERVER_USAGE"===t.digest){const e=new Error("Usage of next-intl APIs in Server Components currently opts into dynamic rendering. This limitation will eventually be lifted, but as a stopgap solution, you can use the `setRequestLocale` API to enable static rendering, see https://next-intl.dev/docs/getting-started/app-router/with-i18n-routing#static-rendering",{cause:t});throw e.digest=t.digest,e}throw t}return t}));async function s(){return r()||await i()}export{s as getRequestLocale};
1
+ import{headers as t}from"next/headers";import{cache as e}from"react";import{HEADER_LOCALE_NAME as n}from"../../shared/constants.js";import{isPromise as r}from"../../shared/utils.js";import{getCachedRequestLocale as o}from"./RequestLocaleCache.js";const s=e((async function(){const e=t();return r(e)?await e:e}));const i=e((async function(){let t;try{t=(await s()).get(n)||void 0}catch(t){if(t instanceof Error&&"DYNAMIC_SERVER_USAGE"===t.digest){const e=new Error("Usage of next-intl APIs in Server Components currently opts into dynamic rendering. This limitation will eventually be lifted, but as a stopgap solution, you can use the `setRequestLocale` API to enable static rendering, see https://next-intl.dev/docs/getting-started/app-router/with-i18n-routing#static-rendering",{cause:t});throw e.digest=t.digest,e}throw t}return t}));async function a(){return o()||await i()}export{a as getRequestLocale};
@@ -1 +1 @@
1
- import{cache as e}from"react";import{_createIntlFormatters as t,_createCache as o,initializeConfig as n}from"use-intl/core";import{getRequestLocale as r}from"./RequestLocale.js";import i from"next-intl/config";const s=e((function(){return Intl.DateTimeFormat().resolvedOptions().timeZone}));const a=e((async function(e,t){let o=e({locale:t,get requestLocale(){return t?Promise.resolve(t):r()}});if(o instanceof Promise&&(o=await o),!o.locale)throw new Error("No locale was returned from `getRequestConfig`.\n\nSee https://next-intl.dev/docs/usage/configuration#i18n-request");return o})),c=e(t),m=e(o);const l=e((async function(e){const t=await a(i,e);return{...n(t),_formatters:c(m()),timeZone:t.timeZone||s()}}));export{l as default};
1
+ import{cache as e}from"react";import{_createIntlFormatters as t,_createCache as o,initializeConfig as r}from"use-intl/core";import{isPromise as n}from"../../shared/utils.js";import{getRequestLocale as i}from"./RequestLocale.js";import s from"next-intl/config";const a=e((function(){return Intl.DateTimeFormat().resolvedOptions().timeZone}));const c=e((async function(e,t){let o=e({locale:t,get requestLocale(){return t?Promise.resolve(t):i()}});if(n(o)&&(o=await o),!o.locale)throw new Error("No locale was returned from `getRequestConfig`.\n\nSee https://next-intl.dev/docs/usage/configuration#i18n-request");return o})),m=e(t),l=e(o);const u=e((async function(e){const t=await c(s,e);return{...r(t),_formatters:m(l()),timeZone:t.timeZone||a()}}));export{u as default};
@@ -1 +1 @@
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
+ 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)}function g(n){return"function"==typeof n.then}export{o as getLocaleAsPrefix,c as getLocalePrefix,h as getSortedPathnames,r as hasPathnamePrefixed,n as isLocalizableHref,g as isPromise,i as matchesPathname,u as normalizeTrailingSlash,e as prefixPathname,f as templateToRegex,t as unprefixPathname};
@@ -15,4 +15,5 @@ export declare function getLocalePrefix<AppLocales extends Locales, AppLocalePre
15
15
  export declare function getLocaleAsPrefix(locale: string): string;
16
16
  export declare function templateToRegex(template: string): RegExp;
17
17
  export declare function getSortedPathnames(pathnames: Array<string>): string[];
18
+ export declare function isPromise<Value>(value: Value | Promise<Value>): value is Promise<Value>;
18
19
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-intl",
3
- "version": "4.0.0-beta-ca3fcd5",
3
+ "version": "4.0.0-beta-ca68f02",
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-ca3fcd5"
115
+ "use-intl": "4.0.0-beta-ca68f02"
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": "9ed16adf3aee9906edc15b1b1a29111a8e2cfef9"
127
+ "gitHead": "bda8ca6ad42b50e8ed7e43f98613d554fb259436"
128
128
  }