Skip to content

Commit

Permalink
fix: Add workaround for OpenTelemetry/Zone.js (#1719)
Browse files Browse the repository at this point in the history
Fixes #1711

Available as `[email protected]`
  • Loading branch information
amannn authored Feb 18, 2025
1 parent d3271f9 commit 1cac9a6
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 15 deletions.
8 changes: 4 additions & 4 deletions packages/next-intl/.size-limit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const config: SizeLimitConfig = [
{
name: "import * from 'next-intl' (react-server)",
path: 'dist/production/index.react-server.js',
limit: '14.735 KB'
limit: '15.355 KB'
},
{
name: "import {createSharedPathnamesNavigation} from 'next-intl/navigation' (react-client)",
Expand All @@ -21,13 +21,13 @@ const config: SizeLimitConfig = [
name: "import {createLocalizedPathnamesNavigation} from 'next-intl/navigation' (react-client)",
path: 'dist/production/navigation.react-client.js',
import: '{createLocalizedPathnamesNavigation}',
limit: '4.115 KB'
limit: '4.125 KB'
},
{
name: "import {createNavigation} from 'next-intl/navigation' (react-client)",
path: 'dist/production/navigation.react-client.js',
import: '{createNavigation}',
limit: '4.115 KB'
limit: '4.125 KB'
},
{
name: "import {createSharedPathnamesNavigation} from 'next-intl/navigation' (react-server)",
Expand Down Expand Up @@ -55,7 +55,7 @@ const config: SizeLimitConfig = [
{
name: "import * from 'next-intl/server' (react-server)",
path: 'dist/production/server.react-server.js',
limit: '14.035 KB'
limit: '14.635 KB'
},
{
name: "import createMiddleware from 'next-intl/middleware'",
Expand Down
4 changes: 3 additions & 1 deletion packages/next-intl/__mocks__/react.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {isPromise} from '../src/shared/utils';

// @ts-expect-error -- React uses CJS
export * from 'react';

export {default} from 'react';

export function use(promise: Promise<unknown> & {value?: unknown}) {
if (!(promise instanceof Promise)) {
if (!isPromise(promise)) {
throw new Error('Expected a promise, got ' + typeof promise);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
Pathnames
} from '../../routing/types';
import {ParametersExceptFirst, Prettify} from '../../shared/types';
import {isLocalizableHref} from '../../shared/utils';
import {isLocalizableHref, isPromise} from '../../shared/utils';
import BaseLink from './BaseLink';
import {
HrefOrHrefWithParams,
Expand Down Expand Up @@ -111,10 +111,9 @@ export default function createSharedNavigationFns<
const isLocalizable = isLocalizableHref(href);

const localePromiseOrValue = getLocale();
const curLocale =
localePromiseOrValue instanceof Promise
? use(localePromiseOrValue)
: localePromiseOrValue;
const curLocale = isPromise(localePromiseOrValue)
? use(localePromiseOrValue)
: localePromiseOrValue;

const finalPathname = isLocalizable
? getPathname(
Expand Down
3 changes: 2 additions & 1 deletion packages/next-intl/src/react-server/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import {describe, expect, it, vi} from 'vitest';
import {getTranslations} from '../server.react-server';
import {isPromise} from '../shared/utils';
import {renderToStream} from './testUtils';
import {
_createCache,
Expand Down Expand Up @@ -73,7 +74,7 @@ describe('performance', () => {
try {
useTranslations('Component');
} catch (promiseOrError) {
if (promiseOrError instanceof Promise) {
if (isPromise(promiseOrError)) {
await promiseOrError;
useTranslations('Component');
} else {
Expand Down
5 changes: 2 additions & 3 deletions packages/next-intl/src/server/react-server/RequestLocale.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import {headers} from 'next/headers';
import {cache} from 'react';
import {HEADER_LOCALE_NAME} from '../../shared/constants';
import {isPromise} from '../../shared/utils';
import {getCachedRequestLocale} from './RequestLocaleCache';

async function getHeadersImpl(): Promise<Headers> {
const promiseOrValue = headers();

// Compatibility with Next.js <15
return promiseOrValue instanceof Promise
? await promiseOrValue
: promiseOrValue;
return isPromise(promiseOrValue) ? await promiseOrValue : promiseOrValue;
}
const getHeaders = cache(getHeadersImpl);

Expand Down
3 changes: 2 additions & 1 deletion packages/next-intl/src/server/react-server/getConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
_createIntlFormatters,
initializeConfig
} from 'use-intl/core';
import {isPromise} from '../../shared/utils';
import {getRequestLocale} from './RequestLocale';
import {getRequestLocale as getRequestLocaleLegacy} from './RequestLocaleLegacy';
import createRequestConfig from './createRequestConfig';
Expand Down Expand Up @@ -72,7 +73,7 @@ See also: https://next-intl.dev/docs/usage/configuration#i18n-request
};

let result = getConfig(params);
if (result instanceof Promise) {
if (isPromise(result)) {
result = await result;
}

Expand Down
7 changes: 7 additions & 0 deletions packages/next-intl/src/shared/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,10 @@ function comparePathnamePairs(a: string, b: string): number {
export function getSortedPathnames(pathnames: Array<string>) {
return pathnames.sort(comparePathnamePairs);
}

export function isPromise<Value>(
value: Value | Promise<Value>
): value is Promise<Value> {
// https://github.com/amannn/next-intl/issues/1711
return typeof (value as any).then === 'function';
}

0 comments on commit 1cac9a6

Please sign in to comment.