| name | column-faceting |
| description | Build faceted filter UIs with columnFacetingFeature, facetedRowModel, facetedUniqueValues, and facetedMinMaxValues. Load for facet counts, numeric ranges, own-filter exclusion, or server-page facet completeness.
|
| metadata | {"type":"sub-skill","library":"@tanstack/table-core","library_version":"9.2.4"} |
| requires | ["core","table-features","column-filtering"] |
| sources | ["TanStack/table:docs/framework/react/guide/column-faceting.md","TanStack/table:packages/table-core/src/features/column-faceting","TanStack/table:examples/react/filters-faceted"] |
This skill builds on core, table-features, and column-filtering. Faceting derives filter choices; it does not render controls.
Setup
import {
columnFacetingFeature,
columnFilteringFeature,
createFacetedMinMaxValues,
createFacetedRowModel,
createFacetedUniqueValues,
createFilteredRowModel,
filterFn_includesString,
filterFn_inNumberRange,
tableFeatures,
} from '@tanstack/table-core'
export const features = tableFeatures({
columnFilteringFeature,
filteredRowModel: createFilteredRowModel(),
filterFns: {
includesString: filterFn_includesString,
inNumberRange: filterFn_inNumberRange,
},
columnFacetingFeature,
facetedRowModel: createFacetedRowModel(),
facetedUniqueValues: createFacetedUniqueValues(),
facetedMinMaxValues: createFacetedMinMaxValues(),
})
Core Patterns
const counts = table.getColumn('status')?.getFacetedUniqueValues() ?? new Map()
const range = table.getColumn('age')?.getFacetedMinMaxValues()
Use unique values for discrete controls and min/max only for numeric ranges.
The filtered model makes facets respond to the table's other active filters.
Register individually imported built-ins under their conventional keys so
columns can reference them by string name; a column may instead receive a
filter function directly without registering it. The full filterFns registry
object still works but bundles every built-in.
Common Mistakes
[HIGH] Registering APIs without model slots
Wrong: tableFeatures({ columnFilteringFeature, columnFacetingFeature })
Correct: tableFeatures({ columnFilteringFeature, columnFacetingFeature, facetedRowModel: createFacetedRowModel(), facetedUniqueValues: createFacetedUniqueValues() })
Each faceting getter needs its matching factory slot.
Source: packages/table-core/src/features/column-faceting/columnFacetingFeature.ts
[MEDIUM] Expecting facet to apply itself
Wrong: column.getFacetedUniqueValues().get(activeValue) === 0
Correct: column.getFacetedUniqueValues().get(activeValue) ?? 0
A column facet intentionally excludes that column's own filter while applying other filters.
Source: docs/framework/react/guide/column-faceting.md
[HIGH] Treating page facets as global
Wrong: const globalCounts = column.getFacetedUniqueValues()
Correct: const globalCounts = await fetchFacetCounts(activeFilters)
With server pagination, client faceting sees only loaded data.
Source: docs/framework/react/guide/column-faceting.md#custom-server-side-faceting
API Discovery
Inspect node_modules/@tanstack/table-core/dist/features/column-faceting/ for exact getters and factory return types.