react-datatable
Reference

Troubleshooting

Use this page when the table is already integrated but something feels wrong. Start with the symptom that is closest to what you see.

First debugging step

Turn on debug logging while reproducing the issue.

<Datatable tableKey="customers" debug />

That helps you distinguish a rendering problem from a state-loading, persistence, or online-query problem.

The table renders unstyled or popovers look broken

Likely cause

Tailwind is not scanning the copied table source, or the required CSS variables are missing.

Check

@import "tailwindcss";

@source ".";
@source "./src/react-datatable";

Also make sure your theme exposes the variables used by the shipped UI, including:

  • --background
  • --foreground
  • --border
  • --input
  • --ring
  • --popover
  • --muted
  • --primary

Usually fixes it

  • add the copied datatable source to Tailwind scanning
  • copy or map the expected design-token variables
  • verify your local wrapper did not drop the table stylesheet imports

Online mode does not load data

Likely cause

The online.query function is throwing, returning the wrong response shape, or receiving unsupported filter/grouping input.

Check

<Datatable
  tableKey="customers"
  online={{
    mode: "pagination",
    queryKey: ["customers"],
    query: async (input) => {
      console.log(input)
      return fetchRows(input)
    },
  }}
/>

Usually fixes it

  • log the query input and confirm the backend accepts the filter, sort, grouping, and pagination fields
  • return rows, totalDataRows, totalRenderedRows, and hasMore
  • set supportedGroupingColumns when only some columns can be grouped server-side

Local mode, saved views, URL sync, and copy links do not require a URL-state provider.

Selection, preview, or saved views point at the wrong rows or columns

Likely cause

Row IDs or column IDs are unstable.

Check

<Datatable
  tableKey="customers"
  data={rows}
  columns={columns}
  getRowId={(row) => row.id}
/>

Usually fixes it

  • use a real row identifier, not an array index
  • keep column id values stable across renders and releases
  • do not derive IDs from labels that product text may change later

Identity drift is one of the fastest ways to break selection, preview, persistence, grouping, and online grouping summaries all at once.

Current-view persistence does not restore what you expected

Likely cause

The wrong persistence scope is loading, or a higher-priority source is overriding it.

Check

  • persistState.adapter is configured
  • tableKey is stable
  • workspaceId and userId match the intended scope
  • storage is available in the current browser context
  • URL state or a saved view is not overriding the persisted state during initialization

The precedence

The coordinated startup model loads state in layers. In practice, persisted state can still be overridden by later sources like selected views or accepted URL parameters.

Usually fixes it

  • confirm the exact table scope keys
  • clear stale persisted state when changing table identity
  • check whether a saved default view is winning
  • check whether acceptUrlParams is applying a one-time shared state on load

Likely cause

This is expected shareable-link behavior, not a bug.

When urlSync uses enabled: false with acceptUrlParams: true, the table reads the datatable params once and then removes them from the address bar.

Usually fixes confusion

  • use this mode for one-time shared links
  • use continuous urlSync if the URL should remain a live product surface
  • document the difference for support and product teams

URL sync is writing too many history entries or back/forward feels wrong

Likely cause

historyMode does not match the page behavior you want.

Check

  • historyMode: "push" creates navigation entries as state changes
  • historyMode: "replace" keeps the URL current without building a long browser history trail

Usually fixes it

  • use replace for dashboards where URL state should stay current quietly
  • use push when back/forward through table states is part of the product experience

Likely cause

The copied link contains a large table state directly in the URL.

Usually fixes it

  • save the state as a named view instead of a URL
  • reduce large filter payloads or overly wide shared state
  • prefer current-view persistence or saved views for heavy internal workflows

Online rows, totals, or grouping counts look wrong

Likely cause

The backend response does not match the online contract.

Check

  • totalDataRows counts matching data records
  • totalRenderedRows includes structural rows like group headers
  • grouping summary matches the same backend scope as rows
  • facets are computed from the same filtered dataset as the returned rows

Usually fixes it

  • keep tenant, permission, search, filters, grouping, and sorting in one backend-owned query scope
  • do not compute facets from a broader or narrower dataset than the rows
  • keep grouped infinite mode explicit about data-row offsets versus rendered-row counts

If route-prefetched initialData appears for the wrong query, re-check initialDataQueryState.

Online grouping selections or persisted grouping values disappear

Likely cause

The current grouping state includes columns your backend does not support.

Check

Set supportedGroupingColumns in the online config when only some groupings are allowed.

Usually fixes it

  • declare the supported grouping columns explicitly
  • let the table sanitize persisted or URL grouping state before it reaches the backend
  • keep your server and docs aligned on which grouped views are actually supported

Filters show the wrong options or filter chips do not match backend truth

Likely cause

Facet keys, filter types, or product-specific filter UI assumptions drifted away from the actual column contract.

Check

  • facet keys match column IDs exactly
  • column filterType matches the UI you expect
  • select-style filters receive option domains that match the actual backend data

Usually fixes it

  • align facet response keys with column IDs
  • keep text, text-list, number, and date filters on the documented UI path
  • treat boolean, ID-list, and custom filters as product-owned extension surfaces unless you built the matching UI yourself

Infinite scrolling feels jumpy or loads the wrong rows

Likely cause

Backend ordering is unstable, or pagination concepts are leaking into infinite mode.

Check

  • the backend ordering is deterministic
  • tie-breakers exist when two rows sort equally
  • offset is treated as a data-row offset
  • prefetchRows is sized for how quickly users move through the list

Usually fixes it

  • make the backend ordering stable for the full active query
  • reset to the start of the result set when filters, search, sorting, or grouping changes
  • keep virtualization concerns separate from online query semantics

Virtualization shows misaligned rows, sticky-column glitches, or rough scrolling

Likely cause

Rendered row heights are not predictable, or too much detail is being forced into the grid.

Check

<Datatable
  tableKey="customers"
  rowHeight={48}
  headerHeight={48}
  virtualization={{ mode: "viewport" }}
/>

Usually fixes it

  • keep row and header heights predictable
  • move long or multi-line detail into preview panels or detail routes
  • tune overscan before changing deeper rendering assumptions
  • keep sticky-column counts modest enough that horizontal scroll remains usable

Grouping shows unexpected empty groups

Likely cause

showEmptyGroups is enabled and the grouped column exposes a finite option domain.

Usually fixes it

  • turn off showEmptyGroups if those zero-count buckets are not useful
  • keep it on only when users genuinely need to see missing categories
  • remember that online mode needs backend support for the same behavior

After copying source updates, the table regressed

Likely cause

A source refresh overwrote local adapters, theme mapping, or product-specific integrations.

Usually fixes it

Before shipping a copied update:

  • compare your local edits against the copied source diff
  • preserve adapter wiring, theme tokens, and product-specific wrappers
  • re-test persistence, views, URL sync, online mode, and bulk actions together
  • run the repository checks, not just a visual smoke test

On this page