Column templates

Custom header and cell rendering with headerTemplate and cellTemplate.

Last updated August 24, 2026

Start from defineColumnsFromRows for the columns you don't need to customize, then declare the ones you do. headerTemplate and cellTemplate accept any React node, so formatting and conditional styling are plain component code.

Formatted currency column#

Column templates

Live example
IdServiceEnvironment NameEnvironment RegionStatusCostCost
1checkout-apiproductionus-east-1healthy1240.5$1,240.50
2billing-workerproductioneu-west-1degraded860.2$860.20
3search-indexstagingus-east-1healthy92.75$92.75
4notificationsproductionus-west-2down305.4$305.40
5analytics-pipelinestagingeu-west-1healthy145$145.00
import { defineColumnsFromRows } from "@gridkitjs/core";
import { DataGridComponent, type ColumnDefinition } from "@gridkitjs/react";

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

const columns: readonly ColumnDefinition<Row>[] = [
  ...defineColumnsFromRows(rows),
  {
    field: "Cost",
    id: "Cost.currency",
    type: "currency",
    headerTemplate: <span className="italic">Cost</span>,
    cellTemplate: ({ value, row }) => (
      <span className={row.Cost > 500 ? "font-semibold text-red-600" : ""}>
        {currency.format(Number(value))}
      </span>
    ),
  },
];

<DataGridComponent columns={columns} dataSource={rows} borders="horizontal" />;

The cellTemplate context#

cellTemplate receives a single CellTemplateContext<Row> argument rather than positional arguments, so a later addition to it is not a breaking change to every template already written.

FieldTypeDescription
valueunknownThis cell's value, read off the column's field path. Untyped since a dotted path's type can't be recovered here — a template narrows it.
rowRowThe whole row, for a template that needs a sibling field.
rowIndexnumberPosition among the rows as rendered — filtered, sorted, and paginated once paginated is on. Not the raw dataSource index.
datasetIndexnumberThis row's absolute position in the whole filtered/sorted/grouped dataset, unaffected by which page is showing. See pagination.
rowIdstringThis row's id, as getRowId (or the position fallback) resolved it.
selectedbooleanWhether this row is selected, so a template can style itself to match.
Edit this page on GitHub