<ResourceTable>, which reads its column definitions from a table registry keyed by table name (products, orders, customers, …). That gives you two levers:
- Extend a built-in table — add, patch, or remove columns (including their filters) without forking the page.
- Define your own table — declare columns once with
defineTable, then render them with<ResourceTable>on your own page.
Add a column to a built-in table
Imperatively, fromsrc/plugins.ts (or a plugin entry):
defineDashboardPlugin — same effect, grouped with your other extensions:
updateColumn instead.
Timing is taken care of. Built-in tables register when their page first loads, which may be after your code runs. Mutations against a table that isn’t registered yet are queued and replayed the moment it appears — and mutations against a table that never registers simply never fire. That means extending an optional feature’s table is safe even when that feature isn’t installed.
Modify or remove built-in columns
updateColumn patches shallowly — pass only the fields you want to change. removeColumn of an unknown key is a no-op.
Column definition
Filter types
When a column isfilterable, filterType decides which filter UI it gets:
filterType | Filter UI | Extra fields |
|---|---|---|
'string' (default) | Text input with contains/equals operators | — |
'boolean' | Yes/no toggle | — |
'number', 'currency' | Numeric comparisons | — |
'date' | Date range picker (store-timezone aware) | — |
'enum' | Fixed option list | filterOptions: [{ value, label }] (required) |
'resource' | Multi-select autocomplete against another resource | filterResource (required) — queryKey, search, hydrate, getOptionLabel |
'tags' | Tag autocomplete | taggableType (required), e.g. 'Spree::Product' |
'resource' filter searches as the admin types and resolves already-selected IDs back to labels on page reload:
key (or ransackAttribute) must be a filterable/sortable attribute the API allows.
Define your own table
For your own list page, declare the table once — typically right next to yourdefineDashboardPlugin call:
<ResourceTable> handles pagination, sorting, the filter panel, column visibility, and URL round-tripping of all of it. See Routes for the page around it — the example Brands plugin shows the complete wiring.
Bulk actions, row actions, reordering
These are props on<ResourceTable>, composed by the page that renders the table:
Reference
table-registry.ts—defineTable,tables, the fullColumnDefunion<ResourceTable>— props for bulk actions, row actions, drag-reordering- Example Brands plugin — a real
defineTable+<ResourceTable>+ products-column extension

