Skip to content

Commit e38a465

Browse files
authored
feat: Detect multiple contexts loaded at the same time (#861)
1 parent b1ca0d2 commit e38a465

File tree

5 files changed

+50
-3
lines changed

5 files changed

+50
-3
lines changed

errors/NUQS-303.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Multiple adapter contexts detected
2+
3+
## Probable cause
4+
5+
This error occurs in [debug mode](https://nuqs.47ng.com/docs/debugging) in
6+
certain monorepo setups where references of the adapter context aren't the same
7+
in different packages, and cause a [`NUQS-404 - nuqs requires an adapter to work with your framework`](./NUQS-404) error.
8+
9+
## Root cause
10+
11+
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
12+
is what adapters are) being re-created in different modules and causing different
13+
references being used for a provider and consumers.
14+
15+
## Possible solutions
16+
17+
See issue [#798](https://github.com/47ng/nuqs/issues/798) for more details.

errors/NUQS-404.md

+15
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,18 @@ If you encounter this error outside of the browser, like in a test
2727
runner (eg: Vitest or Jest), you may use the [testing adapter](https://nuqs.47ng.com/docs/testing)
2828
from `nuqs/adapters/testing` to mock the initial search params and access
2929
setup/assertion testing facilities.
30+
31+
### Monorepo setups
32+
33+
This error can also occur in monorepo setups where components using nuqs hooks
34+
are in different packages resolving to different `nuqs` versions,
35+
leading to different context references being used.
36+
37+
If you [enable debugging](https://nuqs.47ng.com/docs/debugging), you might see a
38+
[`NUQS-303 - Multiple adapter contexts detected`](./NUQS-303) error, confirming
39+
this hypothesis.
40+
41+
For additional clarification, ensure that all packages use compatible versions
42+
of `nuqs` to prevent this issue from arising. See issue
43+
[#798](https://github.com/your-repo/issues/798) for more details and
44+
possible solutions.

packages/nuqs/src/adapters/lib/context.ts

+14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createContext, createElement, useContext, type ReactNode } from 'react'
2+
import { debugEnabled } from '../../debug'
23
import { error } from '../../errors'
34
import type { UseAdapterHook } from './defs'
45

@@ -13,6 +14,19 @@ export const context = createContext<AdapterContext>({
1314
})
1415
context.displayName = 'NuqsAdapterContext'
1516

17+
declare global {
18+
interface Window {
19+
__NuqsAdapterContext?: typeof context
20+
}
21+
}
22+
23+
if (debugEnabled && typeof window !== 'undefined') {
24+
if (window.__NuqsAdapterContext && window.__NuqsAdapterContext !== context) {
25+
console.error(error(303))
26+
}
27+
window.__NuqsAdapterContext = context
28+
}
29+
1630
/**
1731
* Create a custom adapter (context provider) for nuqs to work with your framework / router.
1832
*

packages/nuqs/src/debug.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
const enabled = isDebugEnabled()
1+
export const debugEnabled = isDebugEnabled()
22

33
export function debug(message: string, ...args: any[]) {
4-
if (!enabled) {
4+
if (!debugEnabled) {
55
return
66
}
77
const msg = sprintf(message, ...args)
@@ -15,7 +15,7 @@ export function debug(message: string, ...args: any[]) {
1515
}
1616

1717
export function warn(message: string, ...args: any[]) {
18-
if (!enabled) {
18+
if (!debugEnabled) {
1919
return
2020
}
2121
console.warn(message, ...args)

packages/nuqs/src/errors.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export const errors = {
2+
303: 'Multiple adapter contexts detected. This might happen in monorepos.',
23
404: 'nuqs requires an adapter to work with your framework.',
34
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.',
45
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.',

0 commit comments

Comments
 (0)