Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name: CI/CD
on:
push:
branches:
- master
- beta
- next
pull_request:
types: [opened, reopened, synchronize]
Expand Down
27 changes: 0 additions & 27 deletions .github/workflows/pr-base-enforcement.yml

This file was deleted.

1 change: 1 addition & 0 deletions knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"src/components/audience.tsx",
"src/components/code-block-highlighter.ts",
"src/components/feature-support-matrix.tsx",
"src/components/since-version.tsx",
"src/components/frameworks.tsx",
"src/schemas/changelog-dto.gen.ts"
],
Expand Down
17 changes: 11 additions & 6 deletions packages/docs/content/docs/adapters.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ wrapping it with a `NuqsAdapter{:ts}` context provider:
- <Remix className='inline mr-1.5' role="presentation" /> [Remix](#remix)
- <ReactRouter className='inline mr-1.5' role="presentation" /> [React Router v6](#react-router-v6)
- <ReactRouter className='inline mr-1.5' role="presentation" /> [React Router v7](#react-router-v7)
- <ReactRouter className='inline mr-1.5' role="presentation" /> [React Router v8](#react-router-v8)
- <SinceVersion v="2.9.0" disclaimer="inline"><ReactRouter className='inline mr-1.5' role="presentation" /> [React Router v8](#react-router-v8)</SinceVersion>
- <TanStackRouter className='inline mr-1.5 not-prose' role="presentation"/> [TanStack Router](#tanstack-router)
</HumanContent>

Expand All @@ -34,7 +34,9 @@ wrapping it with a `NuqsAdapter{:ts}` context provider:
- [Remix](#remix)
- [React Router v6](#react-router-v6)
- [React Router v7](#react-router-v7)
<SinceVersion v="2.9.0">
- [React Router v8](#react-router-v8)
</SinceVersion>
- [TanStack Router](#tanstack-router)
</LLMContent>

Expand Down Expand Up @@ -167,8 +169,7 @@ export default function App() {
no longer receives security updates. The `nuqs/adapters/remix` adapter will be
removed in nuqs@3.0.0.

Remix has converged into React Router. Migrate to [React Router v7](#react-router-v7)
or [v8](#react-router-v8) and use the appropriate adapter below.
Remix has converged into React Router. Migrate to [React Router v7](#react-router-v7)<SinceVersion v="2.9.0" disclaimer="inline"> or [v8](#react-router-v8)</SinceVersion> and use the appropriate adapter below.

</Callout>

Expand Down Expand Up @@ -212,10 +213,10 @@ export function ReactRouter() {

- `nuqs/adapters/react-router/v6`
- `nuqs/adapters/react-router/v7`
- `nuqs/adapters/react-router/v8`
- <SinceVersion v="2.9.0" disclaimer='inline'>`nuqs/adapters/react-router/v8`</SinceVersion>

The main difference is where the React Router hooks are imported from:
`react-router-dom` for v6, and `react-router` for v7 & v8.
`react-router-dom` for v6, and `react-router` for v7<SinceVersion v="2.9.0" disclaimer='inline'> & v8</SinceVersion>.
</Callout>

<Callout type="warn" title="Deprecation notice">
Expand All @@ -224,7 +225,7 @@ export function ReactRouter() {
and no longer receives security updates. The `nuqs/adapters/react-router/v6`
adapter will be removed in nuqs@3.0.0.

Upgrade to [React Router v7](#react-router-v7) or [v8](#react-router-v8) and use the
Upgrade to [React Router v7](#react-router-v7)<SinceVersion v="2.9.0" disclaimer="inline"> or [v8](#react-router-v8)</SinceVersion> and use the
appropriate adapter below.

</Callout>
Expand All @@ -247,6 +248,8 @@ export default function App() {
}
```

<SinceVersion v="2.9.0">

## <HumanContent><ReactRouter className='inline mr-2 -mt-1' role="presentation"/></HumanContent>React Router v8 [#react-router-v8]

```tsx title="app/root.tsx"
Expand Down Expand Up @@ -275,6 +278,8 @@ export default function App() {

</Callout>

</SinceVersion>

## <HumanContent><TanStackRouter className='inline mr-2 -mt-1 not-prose' role="presentation"/></HumanContent>TanStack Router [#tanstack-router]

```tsx title="src/routes/__root.tsx"
Expand Down
5 changes: 4 additions & 1 deletion packages/docs/content/docs/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ npm install nuqs
- <Remix className='inline mr-1.5' role="presentation" /> [Remix](/docs/adapters#remix): `@remix-run/react@^2`
- <ReactRouter className='inline mr-1.5' role="presentation" /> [React Router v6](/docs/adapters#react-router-v6): `react-router-dom@^6`
- <ReactRouter className='inline mr-1.5' role="presentation" /> [React Router v7](/docs/adapters#react-router-v7): `react-router@^7`
- <ReactRouter className='inline mr-1.5' role="presentation" /> [React Router v8](/docs/adapters#react-router-v8): `react-router@^8`
- <SinceVersion v="2.9.0" disclaimer="inline"><ReactRouter className='inline mr-1.5' role="presentation" /> [React Router v8](/docs/adapters#react-router-v8): `react-router@^8`</SinceVersion>
- <TanStackRouter className='inline mr-1.5 not-prose' role="presentation"/> [TanStack Router](/docs/adapters#tanstack-router): `@tanstack/react-router@^1`
</HumanContent>

Expand All @@ -47,6 +47,9 @@ npm install nuqs
- [Remix](/docs/adapters#remix): `@remix-run/react@^2`
- [React Router v6](/docs/adapters#react-router-v6): `react-router-dom@^6`
- [React Router v7](/docs/adapters#react-router-v7): `react-router@^7`
<SinceVersion v="2.9.0">
- [React Router v8](/docs/adapters#react-router-v8): `react-router@^8`
</SinceVersion>
- [TanStack Router](/docs/adapters#tanstack-router): `@tanstack/react-router@^1`
</LLMContent>

Expand Down
2 changes: 2 additions & 0 deletions packages/docs/content/docs/options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ adapter prop:
</NuqsAdapter>
```

<SinceVersion v="2.9.0">
<Callout title="Don't break the Back button" type="warn">
Setting `history: 'push'{:ts}` globally will add a new entry to the navigation
history for **every** search param update across your whole app, which is likely
Expand All @@ -413,6 +414,7 @@ Prefer opting into `history: 'push'{:ts}` on a per-hook or per-call basis, only
where the search params contribute to a navigation-like experience (eg: tabs,
modals).
</Callout>
</SinceVersion>

### Processing `URLSearchParams`

Expand Down
2 changes: 2 additions & 0 deletions packages/docs/mdx-components.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { HumanContent, LLMContent } from '@/src/components/audience'
import { FeatureSupportMatrix } from '@/src/components/feature-support-matrix'
import { SinceVersion } from '@/src/components/since-version'
import { Callout } from 'fumadocs-ui/components/callout'
import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock'
import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
Expand All @@ -23,6 +24,7 @@ const components = {
FeatureSupportMatrix,
HumanContent,
LLMContent,
SinceVersion,
Suspense,
Tab,
Tabs,
Expand Down
1 change: 1 addition & 0 deletions packages/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"@types/react": "catalog:react19",
"@types/react-dom": "catalog:react19",
"hast-util-to-jsx-runtime": "^2.3.6",
"msw": "catalog:msw",
"postcss": "^8.5.6",
"prettier-plugin-tailwindcss": "^0.7.2",
"shadcn": "^3.8.2",
Expand Down
18 changes: 18 additions & 0 deletions packages/docs/src/app/styles/tweaks.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@
margin-left: -5.5px;
margin-right: 5.5px;
}

/*
Inline "visible from" cue for unreleased content shown on preview/local
(see <SinceVersion disclaimer="inline">). Rendered as a ::after pseudo-element
so it never fragments the host markdown list the way a block wrapper would.
*/
.nuqs-since-version::after {
content: ' 🏗️ visible from nuqs@' attr(data-since) ' 🏗️';
@apply text-amber-500 dark:text-amber-400;
font-size: 0.85em;
}

/* Collapse a list item whose only content is a hidden inline gate (production),
so it leaves no stray bullet. The gate's marker is targeted via :has() because
the emptied <li> retains whitespace/comment nodes and so is not :empty. */
.prose li:has(> .nuqs-gated-empty) {
display: none;
}
}

/* Center-align copy button in code blocks with single line */
Expand Down
63 changes: 50 additions & 13 deletions packages/docs/src/components/feature-support-matrix.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getPublishedVersion, isReleased } from '@/src/lib/published-version'
import { cn } from '@/src/lib/utils'
import { Callout } from 'fumadocs-ui/components/callout'
import { CheckCircle, XCircle } from 'lucide-react'
Expand Down Expand Up @@ -80,7 +81,7 @@ export function renderFeatureSupportMatrixText(
return sentences.join(' ')
}

export function FeatureSupportMatrix({
export async function FeatureSupportMatrix({
introducedInVersion,
deprecatedInVersion,
highlightUnsupported = false,
Expand All @@ -92,22 +93,17 @@ export function FeatureSupportMatrix({
includeAllFrameworksSupport: true
})
const unsupportedLabel = getUnsupportedFrameworksText(notSupportedIn)
const released = isReleased(introducedInVersion, await getPublishedVersion())

return (
<Callout
type={deprecatedInVersion ? 'warning' : 'success'}
className="pr-1"
>
<Callout type={calloutTone(released, deprecatedInVersion)} className="pr-1">
<div className="flex flex-wrap gap-4">
<span className="text-balance">
Introduced in version <strong>{introducedInVersion}</strong>
{deprecatedInVersion ? (
<>
, and deprecated in version <strong>{deprecatedInVersion}</strong>
</>
) : (
'.'
)}
<VersionLine
introducedInVersion={introducedInVersion}
deprecatedInVersion={deprecatedInVersion}
released={released}
/>
</span>
{!hideFrameworks && (
<div className="not-prose ml-auto flex items-center gap-1 text-xl">
Expand Down Expand Up @@ -207,6 +203,47 @@ export function FeatureSupportMatrix({
)
}

function calloutTone(
released: boolean,
deprecatedInVersion?: string
): 'info' | 'warning' | 'success' {
if (!released) {
return 'info'
}
return deprecatedInVersion ? 'warning' : 'success'
}

function VersionLine({
introducedInVersion,
deprecatedInVersion,
released
}: Pick<
FeatureSupportMatrixProps,
'introducedInVersion' | 'deprecatedInVersion'
> & { released: boolean }) {
if (!released) {
return (
<>
Coming in version <strong>{introducedInVersion}</strong> — not yet
released.
</>
)
}
if (deprecatedInVersion) {
return (
<>
Introduced in version <strong>{introducedInVersion}</strong>, and
deprecated in version <strong>{deprecatedInVersion}</strong>
</>
)
}
return (
<>
Introduced in version <strong>{introducedInVersion}</strong>.
</>
)
}

function parseSupportFrameworks(markdown: string): 'all' | Frameworks[] {
const frameworksValue = markdown.match(/frameworks:\s*('all'|"all"|\[[\s\S]*?\])/)
?.[1]
Expand Down
23 changes: 3 additions & 20 deletions packages/docs/src/components/sidebar-footer.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
'use client'
import { getPublishedVersion } from '@/src/lib/published-version'

import { useEffect, useState } from 'react'

export function SidebarFooter() {
const [version, setVersion] = useState<string | null>(null)
useEffect(() => {
getLatestVersion().then(setVersion).catch(console.error)
}, [])
if (!version) return null
export async function SidebarFooter() {
const version = await getPublishedVersion()
return (
<footer className="ml-2 flex w-full items-baseline gap-2 text-zinc-600 dark:text-zinc-400">
<a
Expand All @@ -20,14 +14,3 @@ export function SidebarFooter() {
</footer>
)
}

async function getLatestVersion() {
try {
const res = await fetch('https://registry.npmjs.org/nuqs').then(r =>
r.json()
)
return res['dist-tags'].latest
} catch {
return 'latest'
}
}
Loading