Integration Recipes
paramsync>recipes

Integration Recipes

Common architectural recipes: TanStack Query, React Server Components (RSC), and URL-driven modals.

TanStack Query Synchronization

Pass reactive query state directly into queryKey arrays. React Query automatically refetches data whenever the URL changes:

TSProductFeed.tsx
'use client';
 
import { useQuery } from '@tanstack/react-query';
import { useQueryState, parseAsString, parseAsInteger } from 'paramsync';
 
export function ProductFeed() {
const [search] = useQueryState('q', parseAsString.withDefault(''), { debounceMs: 300 });
const [page] = useQueryState('page', parseAsInteger.withDefault(1));
 
const { data, isLoading } = useQuery({
queryKey: ['products', search, page],
queryFn: () => fetchProducts({ search, page }),
});
 
if (isLoading) return <div>Loading products...</div>;
return <div>{/* Render items */}</div>;
}
main|paramsync
TypeScript JSXLn 17, Col 1

Server Component (RSC) Direct Parser Usage

Because parsers have zero DOM dependencies, you can import and run them directly in server components and Route Handlers:

TSapp/products/page.tsx
// app/products/page.tsx (Server Component)
import { parseAsString, parseAsInteger } from 'paramsync';
 
interface PageProps {
searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
}
 
export default async function ProductsPage({ searchParams }: PageProps) {
const rawParams = await searchParams;
 
// Validate and parse server-side:
const search = parseAsString.parse((rawParams.q as string) ?? null) ?? '';
const page = parseAsInteger.parse((rawParams.page as string) ?? null) ?? 1;
 
const products = await db.product.findMany({
where: { name: { contains: search } },
skip: (page - 1) * 20,
take: 20,
});
 
return <ProductGrid products={products} />;
}
main|paramsync
TypeScript JSXLn 22, Col 1

URL-Driven Shareable Modals

Control modal visibility and active item selection via query parameters so users can share links directly to open dialogs:

TSUserTable.tsx
'use client';
 
import { useQueryState, parseAsString } from 'paramsync';
 
export function UserTable() {
const [selectedUserId, setSelectedUserId] = useQueryState('editUser', parseAsString);
 
return (
<>
<button onClick={() => setSelectedUserId('usr_102')}>Edit User #102</button>
 
{selectedUserId && (
<EditUserModal
userId={selectedUserId}
onClose={() => setSelectedUserId(null)} // Closes and cleans URL
/>
)}
</>
);
}
main|paramsync
TypeScript JSXLn 20, Col 1