Edge Cases & Troubleshooting

Empty Data

When data is an empty array the table renders a centered empty state with an icon and the message "No records found". If one or more filters are currently active, an additional "Reset Filters" button appears so the user can clear them without leaving the page.

The card view renders the same empty state layout. The pagination bar remains visible and displays "0-0 of 0 records" with all navigation controls disabled.

Null / Undefined Values

The table handles null, undefined, and empty string cell values gracefully across all surfaces:

  • CSV export — cells with null, undefined, or an empty string are written as an empty field in the CSV output rather than the literal string "null" or "undefined".
  • Card view — the corresponding field slot renders as an empty space; no placeholder text is injected.
  • Filter input — setting a column filter value to undefined clears that filter entirely, equivalent to the user clicking the clear button on the filter input.

Loading State

Set isLoading to true to display a skeleton loader while data is being fetched. The skeleton renders 5 placeholder rows, each containing the same number of columns as the active column definition. The toolbar and pagination bar continue to render during loading so layout shift is minimised.

tsx
<ClientSideTable
  columns={columns}
  data={data ?? []}
  isLoading={isLoading}
/>

Filter + Pagination Sync

Applying a filter changes the result set, which may make the current page invalid. The table handles this differently depending on the data mode.

  • Client-side mode — applying any filter automatically resets the current page to page 1. No additional work is required.
  • Server-side mode — the table cannot automatically reset the page because pagination is controlled externally. You must reset the page index to 1 inside your handleFilterChange callback.
In server-side mode, failing to reset the page when filters change can result in an out-of-range page request. Your API may return an empty result set or an error instead of falling back to page 1. Always set page back to 1 inside handleFilterChange.

Locale Switch Mid-Interaction

Changing the active locale while a table is mounted is fully supported. The following updates happen synchronously on the next render:

  • All UI strings (labels, button text, empty state messages) resolve immediately from the new locale bundle.
  • RTL / LTR document direction updates, reversing flex layouts and icon orientations throughout the table.
  • Date values displayed in cells and tooltips reformat according to the locale's date conventions.
  • Pagination arrow icons flip to match the new reading direction.

URL Params on Mount

The table reads URL search parameters exactly once — on initial mount — using an internal mountRef guard. This means that if the URL changes after the component has mounted (for example, via a router push from another part of the page), those changes will not trigger a re-read or update inside the table.

If you need the table state to stay in sync with URL parameters that can change after mount, use a server-side or hybrid data mode and drive state from the parent component. Client-side URL sync is intentionally read-once to avoid conflicts with in-memory state during a session.

Dev Warnings

In development builds the table emits console warnings for common misconfigurations. These warnings are stripped in production. Below are representative examples:

text
[Table] Warning: Column "status" has enableSorting=true but no sortingFn defined. Falling back to alphanumeric sort.

[Table] Warning: Server-side mode detected but onPageChange handler is not provided. Pagination will not work correctly.

[Table] Warning: The "csvExport" feature is enabled but no exportFilename was supplied. Using default filename "export.csv".

[Table] Warning: Plugin "my-plugin" defines onSortChange but the table has sorting disabled. The hook will never be called.

To suppress all dev warnings, set dev.warnings to false in your table config:

tsx
<ClientSideTable
  columns={columns}
  data={data}
  config={{
    dev: {
      warnings: false,
    },
  }}
/>