# Data table: Footers

> Add a footer row to the slotsmith data table, such as a total, from each column's footer definition.

The data table adds a footer row as soon as one column defines `footer`. A footer is a string or a function of the table, so it can show a label or add up the rows, the way `header` builds the head.

```tsx
import { DataTable, type DataTableColumnDef } from "slotsmith/data-table";

type Order = { id: string; item: string; quantity: number; amount: number };

const orders: Order[] = [
  { id: "1", item: "Desk lamp", quantity: 2, amount: 120 },
  { id: "2", item: "Office chair", quantity: 1, amount: 340 },
  { id: "3", item: "Notebooks", quantity: 6, amount: 85.5 },
  { id: "4", item: "Monitor", quantity: 1, amount: 410 },
  { id: "5", item: "Keyboard", quantity: 3, amount: 284.5 },
];

const money = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });

// A <tfoot> appears as soon as one column defines `footer`.
const columns: DataTableColumnDef<Order>[] = [
  { accessorKey: "item", header: "Item", footer: "Total" },
  {
    accessorKey: "quantity",
    header: "Quantity",
    meta: { align: "end" },
    // A footer function gets the table, so it can add up the rows it shows.
    footer: ({ table }) => table.getRowModel().rows.reduce((sum, row) => sum + row.original.quantity, 0),
  },
  {
    accessorKey: "amount",
    header: "Amount",
    meta: { align: "end" },
    cell: ({ getValue }) => money.format(getValue<number>()),
    footer: ({ table }) => money.format(table.getRowModel().rows.reduce((sum, row) => sum + row.original.amount, 0)),
  },
];

export default function Footers() {
  return <DataTable data={orders} columns={columns} getRowId={(order) => order.id} enablePagination={false} />;
}
```

The Item column's footer is the text "Total". The Quantity and Amount footers add up the rows the table shows.

## Footer definitions

`footer` sits on the column definition, next to `header`. A function receives the same context a header does, with `table`: `table.getRowModel().rows` are the rows on the current page after sorting, so the total follows the page. Columns with no `footer` get an empty cell.

`meta: { align: "end" }` on a column aligns its header, cells and footer to the end, which suits numbers.

## The footer parts

The footer renders as the [`Foot`](https://slotsmith.dev/components/data-table/api/#slot-Foot) slot (`<tfoot>`), with a [`FooterRow`](https://slotsmith.dev/components/data-table/api/#slot-FooterRow) holding a [`FooterCell`](https://slotsmith.dev/components/data-table/api/#slot-FooterCell) per column. When the table has a checkbox or drag-handle column, the footer row gets an empty cell for it, so the totals stay under their columns. With no `footer` on any column, the table renders no `<tfoot>` at all.
