Filtering Nested Data in Tanstack Table
Thursday, March 6th, 2025
When working with TanStack Table, filtering over nested data, we are faced with a unique issue. About 9 out of 10 times, our data for tables comes directly from a backend API, and while the table’s default behavior is simple for flat structures, handling deeply nested properties works differently.
Let's look through this code first
Imagine we are fetching from our api, the goal is to populate our table with customers payment data
We can write our type based on the response
We can write the ui using the table properties, and then add a search:
Still simple and straightforward but our challenge lies in filtering over nested data
Understanding Column IDs in TanStack Table
By default, the column ID is determined as follows:
accessorKey
: Uses the provided key directly as the ID.accessorFn
: Derives the ID from theheader
(converted to lowercase, spaces replaced with underscores).Explicit
id
: Uses the manually provided ID.So accessorKey > accessorFn > id
- accessorKey: Uses the provided key as the ID.
- accessorFn: Defaults to deriving the ID from the header (typically lowercased with underscores) unless an ID is explicitly provided.
- Explicit id: Always uses the provided ID, giving you full control.
The Challenge: Nested Data
When fetching data from a backend, you might deal with nested objects. For example, consider the following type:
When filtering nested data in TanStack Table, two things to look out for:
Column IDs ≠ Nested Paths: Filters rely on column IDs, which don’t automatically resolve nested paths like
creator.email
.Dot Notation Traps: Using
accessorKey: "creator.email"
displays data but breaks filtering (searches for literalrow["creator.email"]
).
1. Dot Notation Accessor (Simple but Limited)
We might be tempted to use this solution but it doesnt work as well. While dot notation in accessorKey
(e.g., "creator.email"
) displays nested data correctly, TanStack Table’s default filtering doesn’t automatically traverse nested objects. The filter looks for literal top-level keys like "creator.email"
in your data (which don’t exist), rather than following the nested path creator → email
. You’d need a custom filterFn
to handle this (which isn’t set up by default).
2. Accessor Function + Explicit ID (Recommended)
3. Explicit ID (Simplest)
Conclusion
Filtering nested data in TanStack Table requires understanding how column IDs map to your data structure. While the accessorKey
dot notation might seem tempting for nested properties, its filtering limitations make it unsuitable for real-world use cases.
The recommended approach combines explicit column IDs with accessor functions:
Use
id
to create predictable filter bindingsLeverage
accessorFn
to safely navigate nested objectsMaintain type safety with TypeScript path helpers
For simple cases, explicit IDs with accessorKey
provide a quick solution, but complex nested data demands the robustness of accessorFn
. Remember: your filter's effectiveness depends on how well your column IDs align with your data access patterns.
In my next post, we'll explain how I use dynamic filtering architectures for my tables and how we can use them with nested datasets.