generated from chiffre-io/template-library
-
-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Introducing adapters for other frameworks
BREAKING CHANGE: nuqs now requires wrapping your app with a NuqsAdapter, which is a context provider connecting your framework APIs to the hooks' internals. BREAKING CHANGE: The `startTransition` option no longer automatically sets `shallow: false`. The `Options` type is no longer generic. BREAKING CHANGE: The "use client" directive was not included in the client import (`import {} from 'nuqs'`). It has now been added, meaning that server-side code needs to import from `nuqs/server` to avoid errors like: ``` Error: Attempted to call withDefault() from the server but withDefault is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component. ``` Closes #603, #620.
- Loading branch information
Showing
31 changed files
with
492 additions
and
226 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,4 @@ package-lock.json | |
.next/ | ||
.turbo/ | ||
.vercel | ||
.tsbuildinfo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# `nuqs` requires an adapter to work with your framework | ||
|
||
## Probable cause | ||
|
||
You haven't wrapped the components calling `useQueryState(s)` with | ||
an adapter. | ||
|
||
Adapters are based on React Context, and provide nuqs hooks with | ||
the interfaces to work with your framework. | ||
|
||
## Possible solutions | ||
|
||
Follow the setup instructions to import and wrap your application | ||
using a suitable adapter. | ||
|
||
Example, for Next.js (app router) | ||
|
||
```tsx | ||
// src/app/layout.tsx | ||
import React from 'react' | ||
import { NuqsAdapter } from 'nuqs/adapters/next' | ||
|
||
export default function RootLayout({ | ||
children | ||
}: { | ||
children: React.ReactNode | ||
}) { | ||
return ( | ||
<html> | ||
<body> | ||
<NuqsAdapter>{children}</NuqsAdapter> | ||
</body> | ||
</html> | ||
) | ||
} | ||
``` | ||
|
||
### Test adapter | ||
|
||
If you encounter this error outside of the browser, like in a test | ||
runner, you may use the test adapter from `nuqs/adapters/test` | ||
to mock the context and access setup/assertion testing facilities. | ||
|
||
```tsx | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -130,7 +130,7 @@ to get loading states while the server is re-rendering server components with | |
the updated URL. | ||
|
||
Pass in the `startTransition` function from `useTransition` to the options | ||
to enable this behaviour _(this will set `shallow: false{:ts}` automatically for you)_: | ||
to enable this behaviour: | ||
|
||
```tsx /startTransition/1,3#2 | ||
'use client' | ||
|
@@ -144,7 +144,7 @@ function ClientComponent({ data }) { | |
const [query, setQuery] = useQueryState( | ||
'query', | ||
// 2. Pass the `startTransition` as an option: | ||
parseAsString().withOptions({ startTransition }) | ||
parseAsString().withOptions({ startTransition, shallow: false }) | ||
) | ||
// 3. `isLoading` will be true while the server is re-rendering | ||
// and streaming RSC payloads, when the query is updated via `setQuery`. | ||
|
@@ -157,6 +157,13 @@ function ClientComponent({ data }) { | |
} | ||
``` | ||
|
||
<Callout> | ||
In `[email protected]`, passing `startTransition` as an option automatically sets | ||
`shallow: false{:ts}`. | ||
|
||
This is no longer the case in `nuqs@>=2.0.0`: you'll need to set it explicitly. | ||
</Callout> | ||
|
||
## Clear on default | ||
|
||
By default, when the state is set to the default value, the search parameter is | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import type { AppProps } from 'next/app' | ||
import { NuqsAdapter } from 'nuqs/adapters/next' | ||
|
||
export default function MyApp({ Component, pageProps }: AppProps) { | ||
return ( | ||
<NuqsAdapter> | ||
<Component {...pageProps} /> | ||
</NuqsAdapter> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// This file is needed for projects that have `moduleResolution` set to `node` | ||
// in their tsconfig.json to be able to `import {} from 'nuqs/adpaters/next'`. | ||
// Other module resolutions strategies will look for the `exports` in `package.json`, | ||
// but with `node`, TypeScript will look for a .d.ts file with that name at the | ||
// root of the package. | ||
|
||
export * from '../dist/adapters/next' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// This file is needed for projects that have `moduleResolution` set to `node` | ||
// in their tsconfig.json to be able to `import {} from 'nuqs/adapters/react'`. | ||
// Other module resolutions strategies will look for the `exports` in `package.json`, | ||
// but with `node`, TypeScript will look for a .d.ts file with that name at the | ||
// root of the package. | ||
|
||
export * from '../dist/adapters/react' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// This file is needed for projects that have `moduleResolution` set to `node` | ||
// in their tsconfig.json to be able to `import {} from 'nuqs/adpaters/testing'`. | ||
// Other module resolutions strategies will look for the `exports` in `package.json`, | ||
// but with `node`, TypeScript will look for a .d.ts file with that name at the | ||
// root of the package. | ||
|
||
export * from '../dist/adapters/testing' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import type { Options } from '../defs' | ||
|
||
export type AdapterOptions = Pick<Options, 'history' | 'scroll' | 'shallow'> | ||
|
||
export type UpdateUrlFunction = ( | ||
search: URLSearchParams, | ||
options: Required<AdapterOptions> | ||
) => void | ||
|
||
export type UseAdapterHook = () => AdapterInterface | ||
|
||
export type AdapterInterface = { | ||
searchParams: URLSearchParams | ||
updateUrl: UpdateUrlFunction | ||
rateLimitFactor?: number | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { createContext, createElement, useContext, type ReactNode } from 'react' | ||
import { error } from '../errors' | ||
import type { UseAdapterHook } from './defs' | ||
|
||
export type AdapterContext = { | ||
useAdapter: UseAdapterHook | ||
} | ||
|
||
export const context = createContext<AdapterContext>({ | ||
useAdapter() { | ||
throw new Error(error(404)) | ||
} | ||
}) | ||
context.displayName = 'NuqsAdapterContext' | ||
|
||
export function createAdapterProvider(useAdapter: UseAdapterHook) { | ||
return ({ children, ...props }: { children: ReactNode }) => | ||
createElement( | ||
context.Provider, | ||
{ ...props, value: { useAdapter } }, | ||
children | ||
) | ||
} | ||
|
||
export function useAdapter() { | ||
const value = useContext(context) | ||
if (!('useAdapter' in value)) { | ||
throw new Error(error(404)) | ||
} | ||
return value.useAdapter() | ||
} |
Oops, something went wrong.