Features
List Views
Every Vextro collection gets a list view page with filtering, sorting, full-text search, cursor-based pagination, and bulk operations.
Default columns
Fields with listColumn: true appear as default columns, ordered by field definition:
export const posts = defineVextroCollection({
slug: "posts",
label: "Posts",
collectionType: "content",
tableName: "posts",
fields: {
title: f.text({ listColumn: true, listColumnWidth: "large", searchable: true }),
status: f.select({ options: ["draft", "published"], listColumn: true, listColumnWidth: "small" }),
publishedAt: f.datetime({ listColumn: true, listColumnWidth: "medium" }),
body: f.richText(), // not shown in list
},
}); | Width | Use Case |
|---|---|
"auto" | Content-based width. |
"small" | Status badges, dates, toggles. |
"medium" | Standard fields. |
"large" | Titles, descriptions. |
Collection list config
listConfig: {
columns: ["title", "status", "publishedAt"],
searchableFields: ["title", "slug"],
defaultSort: "publishedAt",
defaultSortDirection: "desc",
}, Filtering
| Operator | Description | Applicable Types |
|---|---|---|
equals | Exact match | All |
contains | Substring match | Text |
startsWith | Prefix match | Text |
gt, gte, lt, lte | Numeric comparisons | Number, date |
in | Value in set | Select, radio |
exists | Has a value | All |
Combine filters with and or or logic:
const query: VextroListQuery = {
filters: [
{ field: "status", operator: "equals", value: "published" },
{ field: "publishedAt", operator: "gte", value: Date.now() - 86400000 },
],
filterLogic: "and",
}; Sorting and search
Sort by any sortable field. Fields with searchable: true are included in the search input.
Pagination
Cursor-based pagination with a default page size of 25. Use createPaginationState(25) and getPaginationInfo() from vextro/listing for display labels like "Showing 1-25 of ~142". Use mergePages() for infinite scroll patterns.
Bulk actions
Select multiple documents with checkboxes for bulk delete, status change, or export.