- Introduction
- Pitch
- Hogwarts
- Live Demo
- MVP
- Roadmap
- Launch Sprint
- PRD
- Get Started
- Localhost
- Architecture
- Structure
- Pattern
- Page
- Layout
- Content
- Types
- Config
- Actions
- Queries
- Authorization
- Validation
- Form
- Table
- Detail
- Card
- Util
- Hooks
- List Params
- Views
- README.md
- ISSUE.md
- Technology Stack
- Database
- File
- CDN Assets
- Entry Points
- Dashboard
- Authentication
- Credentials
- OAuth
- Flow Diagrams
- Multi-Tenancy
- Offline
- Onboarding
- Onboarding Videos
- Add Values
- Admission
- Application
- Attendance
- Compliance
- Profile
- Exams
- Exam Wizard
- Timetable
- Classrooms
- Notifications
- Conference
- LMS (Lumos)
Finance
- Finance
- Fee Management
- Invoice
- Wallet
- Salary
- Payroll
- Timesheet
- Expenses
- Budget
- Receipt
- Accounts
- Banking
- Reports
- Dashboard
- Permissions
- Messages
- Integration Flow
- Provision
- AI Document Processing
- Document Intelligence
- Internationalization
- Translation
- Translation Guide
- Icons
- Docs Factory
- Inspiration
- Listings
- Teachers
- Students
- Catalog
- Library
- Contributing
- Code of conduct
- GitHub Workflow
- Database Seeds
- Database Safety
- Test Accounts
- Playwright
- Prettier
- Block Rebound
Sales & GTM
list-params.ts defines the nuqs URL search-param cache for a list view. One cache per feature, exported as <feature>SearchParams plus a co-exported type alias. The pattern is uniform across ~18 files (~22 lines each).
Rules
| # | Rule |
|---|---|
| 1 | Name the file list-params.ts — not searchparams.ts, page-params.ts |
| 2 | Single createSearchParamsCache call per feature |
| 3 | Export type alias from the parsed cache |
| 4 | Column filter keys must match accessorKey in columns.tsx |
| 5 | Always include page, perPage, sort |
Canonical example
import {
createSearchParamsCache,
parseAsInteger,
parseAsString,
} from "nuqs/server"
import { getSortingStateParser } from "@/components/table/lib/parsers"
export const teachersSearchParams = createSearchParamsCache({
page: parseAsInteger.withDefault(1),
perPage: parseAsInteger.withDefault(20),
// column filters (keys must match column accessorKeys)
name: parseAsString.withDefault(""),
emailAddress: parseAsString.withDefault(""),
status: parseAsString.withDefault(""),
sort: getSortingStateParser().withDefault([]),
})
export type TeachersSearch = Awaited<
ReturnType<typeof teachersSearchParams.parse>
>Usage in page.tsx
import type { SearchParams } from "nuqs/server"
import { teachersSearchParams } from "@/components/.../list-params"
import { Content } from "@/components/.../content"
interface PageProps {
searchParams: Promise<SearchParams>
}
export default async function TeachersPage({ searchParams }: PageProps) {
const parsed = teachersSearchParams.parse(await searchParams)
return <Content searchParams={parsed} />
}Usage in content.tsx
import { type TeachersSearch } from "./list-params"
import { getTeacherList } from "./queries"
interface ContentProps {
searchParams: TeachersSearch
}
export async function Content({ searchParams }: ContentProps) {
const { page, perPage, name, status, sort } = searchParams
const { rows, count } = await getTeacherList(schoolId, {
page, perPage, search: name, status: status || undefined, sort,
})
return <Table data={rows} pageCount={Math.ceil(count / perPage)} />
}Parser types
| Parser | Type | Used for |
|---|---|---|
parseAsInteger | number | page, perPage |
parseAsString | string | Column filters, search text |
getSortingStateParser() | SortingState | Table sorting state |
Naming
| Pattern | Example |
|---|---|
<feature>SearchParams | teachersSearchParams, admissionSearchParams |
<Feature>Search | TeachersSearch, AdmissionSearch |
Anti-patterns
- Different filenames —
saas-dashboard/billing/validation.tsmixed with Zod,attendance/page-params.ts. Standardise onlist-params.ts. - Missing
list-params.ts(~10 features with tables) — search params defined inline incontent.tsx. - Search-param parsing inside
content.tsx— extract to its own file.
File layout
src/components/<feature>/
list-params.ts # Search-param cache (this file)
content.tsx # Imports parsed params
table.tsx # Syncs with URL state
columns.tsx # accessorKeys match list-params keys