Skip to content

Commit 7f4fd85

Browse files
committed
feat: Detect multiple contexts loaded at the same time
1 parent 8d8022c commit 7f4fd85

File tree

4 files changed

+35
-3
lines changed

4 files changed

+35
-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.

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)
@@ -10,7 +10,7 @@ export function debug(message: string, ...args: any[]) {
1010
}
1111

1212
export function warn(message: string, ...args: any[]) {
13-
if (!enabled) {
13+
if (!debugEnabled) {
1414
return
1515
}
1616
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)