nuqs Adapter
Sync data table state to the URL with nuqs in Next.js.
The nuqs adapter uses nuqs to persist filter state, sorting, and pagination in URL search parameters. This is the recommended adapter for Next.js projects.
Installation
npx shadcn@latest add https://ada-table.vercel.app/r/nuqs-adapter.jsonThis installs nuqs and the adapter files automatically.
Setup
1. Add the NuqsAdapter provider
Wrap your application with the nuqs adapter in your root layout:
import { NuqsAdapter } from "nuqs/adapters/next/app";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<NuqsAdapter>{children}</NuqsAdapter>
</body>
</html>
);
}2. Create a search params cache
In a shared file, create a search params cache using the built-in dataTableParsers:
import { createSearchParamsCache } from "nuqs/server";
import { dataTableParsers } from "@/components/data-table/integrations/nuqs";
export const searchParamsCache = createSearchParamsCache(dataTableParsers);3. Parse search params on the server
In your server component, parse the URL search params:
import { searchParamsCache } from "@/lib/search-params";
export default async function Page({
searchParams,
}: {
searchParams: Promise<Record<string, string | string[]>>;
}) {
const search = searchParamsCache.parse(await searchParams);
// Use search.filters, search.sort, search.page, search.perPage
// to query your database
}4. Use the adapter in your client component
"use client";
import { useNuqsSearchAdapter } from "@/components/data-table/integrations/nuqs";
import { useDataTable } from "@/components/data-table/hooks/use-data-table";
export function TasksTable({ data, pageCount }) {
const adapter = useNuqsSearchAdapter();
const { table, filterColumns, filters, joinOperator, actions } = useDataTable({
data,
columns,
columnsConfig,
strategy: "server",
adapter,
pageCount,
});
// Render your table...
}Options
useNuqsSearchAdapter accepts an optional Options object from nuqs:
const adapter = useNuqsSearchAdapter({
shallow: false, // default: false — triggers server re-renders
history: "replace", // default: "replace"
scroll: false,
throttleMs: 50,
});The default shallow: false ensures that URL changes trigger Next.js server-side re-renders, which is required for server-side filtering to work.
URL Format
The adapter serializes filter state to URL search params:
?filters=[{"columnId":"status","type":"option","operator":"is any of","values":["todo","in-progress"],"filterId":"abc123"}]
&joinOperator=and
&sort=[{"id":"createdAt","desc":true}]
&page=1
&perPage=10Parsers
The built-in dataTableParsers object provides nuqs parsers for all search state fields:
import { dataTableParsers } from "@/components/data-table/integrations/nuqs";
// dataTableParsers = {
// filters: parseAsJson(filtersSchema).withDefault([]),
// joinOperator: parseAsStringLiteral(["and", "or"]).withDefault("and"),
// page: parseAsInteger.withDefault(1),
// perPage: parseAsInteger.withDefault(10),
// sort: parseAsJson(sortSchema).withDefault([]),
// }You can use these parsers with createSearchParamsCache for server-side parsing and with createSerializer for building links.