Search

Add case-insensitive search to one paginated plugin table with withPagination and the shared table UI.

withPagination includes built-in multi-column search filtering. When search columns are specified, incoming ?search= query parameters automatically apply case-insensitive ILIKE clauses across the chosen columns.

Site-Wide Search

For site-wide search across multiple collections and models, see Search & Discovery.

Quick start

ContentDataTable is VitNode's reusable table UI: it renders rows, toolbar, search, sorting, and pagination. It does not fetch data. See Data Table for the navigation provider it needs around it.

Accept search in the route query

Extend zodPaginationQuery to accept the optional search string:

plugins/reactions/src/api/modules/reactions/routes/get.route.ts
import { z } from "@hono/zod-openapi"
import { zodPaginationQuery } from "@vitnode/core/api/lib/with-pagination"

request: {
  query: zodPaginationQuery.extend({
    search: z.string().optional(), 
  }),
}

Supply searchable columns

List the columns to filter in the search array:

plugins/reactions/src/api/modules/reactions/routes/get.route.ts
const data = await withPagination({
  c,
  params: { query },
  table: reactions,
  primaryCursor: reactions.id,
  search: [reactions.emoji, reactions.description], // Filters across both columns
  query: async ({ cursorSelection, limit, where, orderBy }) =>
    await c
      .get('db')
      .select({ ...getColumns(reactions), ...cursorSelection })
      .from(reactions)
      .where(where)
      .orderBy(orderBy)
      .limit(limit),
})

Show the table search input

Enable the shared table UI after its route loader returns { edges, pageInfo }:

src/views/reactions-table.tsx
<ContentDataTable
  id="reactions-table"
  columns={columns}
  edges={data.edges}
  pageInfo={data.pageInfo}
  order={{ defaultOrder: { column: 'emoji', order: 'asc' } }}
  search
  searchPlaceholder="Search reactions..."
/>

The table automatically updates the ?search= query parameter as the user types with debouncing.

Learn More