# Data Table Component in the Tanstack Start Supabase SaaS kit

> Learn how to use the Data Table component in the Tanstack Start Supabase SaaS kit

*Canonical: https://makerkit.dev/docs/tanstack-supabase/components/data-table*

---

The DataTable component is a powerful and flexible table component built on top of TanStack Table (React Table v8). It provides a range of features for displaying and interacting with tabular data, including pagination, sorting, and custom rendering.

## Usage

```tsx
import { DataTable } from '@kit/ui/enhanced-data-table';

function MyComponent() {
  const columns = [
    // Define your columns here
  ];

  const data = [
    // Your data array
  ];

  return (
    <DataTable
      columns={columns}
      data={data}
      pageSize={10}
      pageIndex={0}
      pageCount={5}
    />
  );
}
```

## Props

- `data: T[]` (required): An array of objects representing the table data.
- `columns: ColumnDef<T>[]` (required): An array of column definitions.
- `pageIndex?: number`: The current page index (0-based).
- `pageSize?: number`: The number of rows per page.
- `pageCount?: number`: The total number of pages.
- `onPaginationChange?: (pagination: PaginationState) => void`: Callback function for pagination changes.
- `tableProps?: React.ComponentProps<typeof Table>`: Additional props to pass to the underlying Table component.

## Pagination

The DataTable component handles pagination internally but can also be controlled externally. It provides navigation buttons for first page, previous page, next page, and last page.

## Sorting

Sorting is handled internally by the component. Click on column headers to sort by that column.

## Filtering

The component supports column filtering, which can be implemented in the column definitions.

## Example with a route loader and server function

In Tanstack Start there is no `ServerDataLoader` component. Instead, fetch the data in a server function, call it from the route `loader`, and pass the paginated result down to the `DataTable`.

First, define a server function that queries Supabase and returns the page of data plus pagination metadata. This is the same pattern used by `apps/web/src/lib/server/admin.functions.ts`:

```tsx title="apps/web/src/lib/server/accounts.functions.ts"
import { createServerFn } from '@tanstack/react-start';
import * as z from 'zod';

import { adminFunctionMiddleware } from '@kit/function-middleware/functions';
import { getSupabaseServerClient } from '@kit/supabase/server-client';

const PAGE_SIZE = 10;

const AccountsSearchSchema = z.object({
  page: z.number().int().positive().default(1),
});

export const fetchAccounts = createServerFn({ method: 'GET' })
  .middleware(adminFunctionMiddleware)
  .validator(AccountsSearchSchema)
  .handler(async ({ data }) => {
    const client = getSupabaseServerClient();
    const from = (data.page - 1) * PAGE_SIZE;
    const to = from + PAGE_SIZE - 1;

    const {
      data: accounts,
      count,
      error,
    } = await client
      .from('accounts')
      .select('*', { count: 'exact' })
      .order('created_at', { ascending: false })
      .range(from, to);

    if (error) {
      throw error;
    }

    return {
      data: accounts,
      page: data.page,
      pageSize: PAGE_SIZE,
      pageCount: Math.ceil((count ?? 0) / PAGE_SIZE),
    };
  });
```

Then wire the server function into the route `loader` and render the `DataTable` with the loader data:

```tsx title="apps/web/src/routes/admin/accounts/index.tsx"
import { createFileRoute } from '@tanstack/react-router';

import { DataTable } from '@kit/ui/enhanced-data-table';

import { fetchAccounts } from '#/lib/server/accounts.functions.ts';

export const Route = createFileRoute('/admin/accounts/')({
  validateSearch: (search: Record<string, unknown>) => ({
    page: typeof search.page === 'number' && search.page > 0 ? search.page : 1,
  }),
  loaderDeps: ({ search }) => search,
  loader: ({ deps }) => fetchAccounts({ data: deps }),
  component: AccountsPage,
});

function AccountsPage() {
  const { data, page, pageSize, pageCount } = Route.useLoaderData();

  return (
    <DataTable
      columns={[
        // Define your columns here
      ]}
      data={data}
      pageIndex={page - 1}
      pageSize={pageSize}
      pageCount={pageCount}
    />
  );
}
```

This example demonstrates how to fetch data from a Supabase table in a server function and pass it to the `DataTable`. The route `loader` handles data fetching and pagination (re-running whenever the `page` search param changes via `loaderDeps`), while the `DataTable` takes care of rendering and client-side interactions.

## Customization

The DataTable component is built with customization in mind. You can customize the appearance using Tailwind CSS classes and extend its functionality by passing custom props to the underlying Table component.

## Internationalization

The component uses the `Trans` component for internationalization. Ensure you have your i18n setup correctly to leverage this feature.

The DataTable component provides a powerful and flexible solution for displaying tabular data in your React applications, with built-in support for common table features and easy integration with server-side data loading.
