From c08de5518058963cf9305e0bad71b813acc87043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Best?= Date: Tue, 14 Jan 2025 22:48:24 +0100 Subject: [PATCH 1/2] feat: Detect multiple contexts loaded at the same time --- errors/NUQS-303.md | 17 +++++++++++++++++ packages/nuqs/src/adapters/lib/context.ts | 14 ++++++++++++++ packages/nuqs/src/debug.ts | 6 +++--- packages/nuqs/src/errors.ts | 1 + 4 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 errors/NUQS-303.md diff --git a/errors/NUQS-303.md b/errors/NUQS-303.md new file mode 100644 index 000000000..4ae69ff4a --- /dev/null +++ b/errors/NUQS-303.md @@ -0,0 +1,17 @@ +# Multiple adapter contexts detected + +## Probable cause + +This error occurs in [debug mode](https://nuqs.47ng.com/docs/debugging) in +certain monorepo setups where references of the adapter context aren't the same +in different packages, and cause a [`NUQS-404 - nuqs requires an adapter to work with your framework`](./NUQS-404) error. + +## Root cause + +As described in the [React docs](https://react.dev/reference/react/useContext#my-component-doesnt-see-the-value-from-my-provider), this can happen with Context providers (which +is what adapters are) being re-created in different modules and causing different +references being used for a provider and consumers. + +## Possible solutions + +See issue [#798](https://github.com/47ng/nuqs/issues/798) for more details. diff --git a/packages/nuqs/src/adapters/lib/context.ts b/packages/nuqs/src/adapters/lib/context.ts index 034fa773a..33ee54d44 100644 --- a/packages/nuqs/src/adapters/lib/context.ts +++ b/packages/nuqs/src/adapters/lib/context.ts @@ -1,4 +1,5 @@ import { createContext, createElement, useContext, type ReactNode } from 'react' +import { debugEnabled } from '../../debug' import { error } from '../../errors' import type { UseAdapterHook } from './defs' @@ -13,6 +14,19 @@ export const context = createContext({ }) context.displayName = 'NuqsAdapterContext' +declare global { + interface Window { + __NuqsAdapterContext?: typeof context + } +} + +if (debugEnabled && typeof window !== 'undefined') { + if (window.__NuqsAdapterContext && window.__NuqsAdapterContext !== context) { + console.error(error(303)) + } + window.__NuqsAdapterContext = context +} + /** * Create a custom adapter (context provider) for nuqs to work with your framework / router. * diff --git a/packages/nuqs/src/debug.ts b/packages/nuqs/src/debug.ts index b3cf4a651..8bf6bcaa2 100644 --- a/packages/nuqs/src/debug.ts +++ b/packages/nuqs/src/debug.ts @@ -1,7 +1,7 @@ -const enabled = isDebugEnabled() +export const debugEnabled = isDebugEnabled() export function debug(message: string, ...args: any[]) { - if (!enabled) { + if (!debugEnabled) { return } const msg = sprintf(message, ...args) @@ -15,7 +15,7 @@ export function debug(message: string, ...args: any[]) { } export function warn(message: string, ...args: any[]) { - if (!enabled) { + if (!debugEnabled) { return } console.warn(message, ...args) diff --git a/packages/nuqs/src/errors.ts b/packages/nuqs/src/errors.ts index 072794769..a7fe9ca6e 100644 --- a/packages/nuqs/src/errors.ts +++ b/packages/nuqs/src/errors.ts @@ -1,4 +1,5 @@ export const errors = { + 303: 'Multiple adapter contexts detected. This might happen in monorepos.', 404: 'nuqs requires an adapter to work with your framework.', 409: 'Multiple versions of the library are loaded. This may lead to unexpected behavior. Currently using `%s`, but `%s` (via the %s adapter) was about to load on top.', 414: 'Max safe URL length exceeded. Some browsers may not be able to accept this URL. Consider limiting the amount of state stored in the URL.', From 639f8c7ed45ee1389171cf0f6acb091ab5fcbc3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Best?= Date: Thu, 13 Feb 2025 17:07:04 +0100 Subject: [PATCH 2/2] doc: Update NUQS-404 to point to NUQS-303 --- errors/NUQS-404.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/errors/NUQS-404.md b/errors/NUQS-404.md index a91ea26c4..a235a7d40 100644 --- a/errors/NUQS-404.md +++ b/errors/NUQS-404.md @@ -27,3 +27,18 @@ If you encounter this error outside of the browser, like in a test runner (eg: Vitest or Jest), you may use the [testing adapter](https://nuqs.47ng.com/docs/testing) from `nuqs/adapters/testing` to mock the initial search params and access setup/assertion testing facilities. + +### Monorepo setups + +This error can also occur in monorepo setups where components using nuqs hooks +are in different packages resolving to different `nuqs` versions, +leading to different context references being used. + +If you [enable debugging](https://nuqs.47ng.com/docs/debugging), you might see a +[`NUQS-303 - Multiple adapter contexts detected`](./NUQS-303) error, confirming +this hypothesis. + +For additional clarification, ensure that all packages use compatible versions +of `nuqs` to prevent this issue from arising. See issue +[#798](https://github.com/your-repo/issues/798) for more details and +possible solutions.