using-nuqs

安装量: 58
排名: #12883

安装

npx skills add https://github.com/andrelandgraf/fullstackrecipes --skill using-nuqs

Working with nuqs

Manage React state in URL query parameters with nuqs. Covers Suspense boundaries, parsers, clearing state, and deep-linkable dialogs.

Implement Working with nuqs

Manage React state in URL query parameters with nuqs for shareable filters, search, and deep-linkable dialogs.

See:

Resource: using-nuqs in Fullstack Recipes URL: https://fullstackrecipes.com/recipes/using-nuqs Suspense Boundary Pattern

nuqs uses useSearchParams behind the scenes, requiring a Suspense boundary. Wrap nuqs-using components with Suspense via a wrapper component to keep the boundary colocated:

import { Suspense } from "react";

type SearchInputProps = { placeholder?: string; };

// Public component with built-in Suspense export function SearchInput(props: SearchInputProps) { return ( }> ); }

"use client";

import { useQueryState, parseAsString } from "nuqs";

// Internal client component that uses nuqs function SearchInputClient({ placeholder = "Search..." }: SearchInputProps) { const [search, setSearch] = useQueryState("q", parseAsString.withDefault(""));

return ( setSearch(e.target.value || null)} placeholder={placeholder} /> ); }

This pattern allows consuming components to use SearchInput without adding Suspense themselves.

State to URL Query Params

Replace useState with useQueryState to sync state to the URL:

"use client";

import { useQueryState, parseAsString, parseAsBoolean, parseAsArrayOf, } from "nuqs";

// String state (search, filters) const [search, setSearch] = useQueryState("q", parseAsString.withDefault(""));

// Boolean state (toggles) const [showArchived, setShowArchived] = useQueryState( "archived", parseAsBoolean.withDefault(false), );

// Array state (multi-select) const [tags, setTags] = useQueryState( "tags", parseAsArrayOf(parseAsString).withDefault([]), );

Clear State

Set to null to remove from URL:

// Clear single param setSearch(null);

// Clear all filters function clearFilters() { setSearch(null); setTags(null); setShowArchived(null); }

When using .withDefault(), setting to null clears the URL param but returns the default value.

Deep-Linkable Dialogs

Control dialog visibility with URL params for shareable links:

import { Suspense } from "react";

type DeleteDialogProps = { onDelete: (id: string) => Promise; };

// Public component with built-in Suspense export function DeleteDialog(props: DeleteDialogProps) { return ( ); }

"use client";

import { useQueryState, parseAsString } from "nuqs"; import { AlertDialog, AlertDialogContent } from "@/components/ui/alert-dialog";

function DeleteDialogClient({ onDelete }: DeleteDialogProps) { const [deleteId, setDeleteId] = useQueryState("delete", parseAsString);

async function handleDelete() { if (!deleteId) return; await onDelete(deleteId); setDeleteId(null); }

return ( !open && setDeleteId(null)}> {/ Confirmation UI /} ); }

Open the dialog programmatically:

// Open delete dialog for specific item setDeleteId("item-123");

// Deep link: /items?delete=item-123

Opening Dialogs from Buttons

Use a trigger button to open the dialog:

function ItemRow({ item }: { item: Item }) { const [, setDeleteId] = useQueryState("delete", parseAsString);

return ( ); }

References nuqs Documentation nuqs Parsers

返回排行榜