---
title: "SSRM Row Height"
enterprise: true
framework: react
version: "36.1.0"
---

# SSRM Row Height

Learn how to set Row Height when using the Server-Side Row Model.

## Dynamic Row Height

To enable [Dynamic Row Height](https://www.ag-grid.com/react-data-grid/row-height/) when using the Server-Side Row Model you need to provide an implementation for the `getRowHeight` Grid Options property. This is demonstrated in the example below:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `getRowHeight` | `GetRowHeight` |  |  | Callback version of property `rowHeight` to set height for each row individually. Function should return a positive number of pixels, or return `null`/`undefined` to use the default row height. |

#### Dynamic Row Height Example

```tsx
("use client");

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import {
  AutoGroupColumnDef,
  ColDef,
  ColGroupDef,
  GetRowHeight,
  GridApi,
  GridOptions,
  GridReadyEvent,
  IServerSideDatasource,
  ModuleRegistry,
  RowHeightParams,
  RowModelType,
  enableDevValidations,
} from "ag-grid-community";
import {
  RowGroupingModule,
  ServerSideRowModelModule,
} from "ag-grid-enterprise";
import { FakeServer } from "./fakeServer";
import { IOlympicData } from "./interfaces";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

const modules = [RowGroupingModule, ServerSideRowModelModule];

const getServerSideDatasource: (server: any) => IServerSideDatasource = (
  server: any,
) => {
  return {
    getRows: (params) => {
      console.log("[Datasource] - rows requested by grid: ", params.request);
      const response = server.getData(params.request);
      // adding delay to simulate real server call
      setTimeout(() => {
        if (response.success) {
          // call the success callback
          params.success({
            rowData: response.rows,
            rowCount: response.lastRow,
          });
        } else {
          // inform the grid request failed
          params.fail();
        }
      }, 200);
    },
  };
};

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "country", rowGroup: true, hide: true },
    { field: "year", rowGroup: true, hide: true },
    { field: "gold", aggFunc: "sum" },
    { field: "silver", aggFunc: "sum" },
    { field: "bronze", aggFunc: "sum" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
    };
  }, []);
  const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
    return {
      flex: 1,
      minWidth: 180,
    };
  }, []);
  const getRowHeight = useCallback((params: RowHeightParams) => {
    if (params.node.level === 0) {
      return 80;
    }
    if (params.node.level === 1) {
      return 60;
    }
    return 40;
  }, []);

  const onGridReady = useCallback((params: GridReadyEvent) => {
    fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
      .then((resp) => resp.json())
      .then((data: IOlympicData[]) => {
        // setup the fake server with entire dataset
        const fakeServer = new FakeServer(data);
        // create datasource with a reference to the fake server
        const datasource = getServerSideDatasource(fakeServer);
        // register the datasource with the grid
        params.api!.setGridOption("serverSideDatasource", datasource);
      });
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            autoGroupColumnDef={autoGroupColumnDef}
            rowModelType={"serverSide"}
            getRowHeight={getRowHeight}
            suppressAggFuncInHeader={true}
            onGridReady={onGridReady}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Dynamic Row Height Example](https://www.ag-grid.com/examples/server-side-model-row-height/dynamic-row-height/reactFunctionalTs/)

> **Note**
>
> Ensure `maxBlocksInCache` is not set when using dynamic row height.

## Auto Row Height

To have the grid calculate the row height based on the cell contents, set `autoHeight=true` on columns that require variable height. The grid will calculate the height once when the data is loaded into the grid.

In the example below, Column A & B have `autoHeight=true` and `wrapText=true`. See [Row Height](https://www.ag-grid.com/react-data-grid/row-height/) for details on these properties.

#### Auto Row Height Example

```tsx
("use client");

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import {
  AutoGroupColumnDef,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  IServerSideDatasource,
  ModuleRegistry,
  RowAutoHeightModule,
  RowModelType,
  enableDevValidations,
} from "ag-grid-community";
import {
  RowGroupingModule,
  ServerSideRowModelModule,
} from "ag-grid-enterprise";
import { getData } from "./data";
import { FakeServer } from "./fakeServer";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

const modules = [
  RowAutoHeightModule,
  RowGroupingModule,
  ServerSideRowModelModule,
];

const getServerSideDatasource: (server: any) => IServerSideDatasource = (
  server: any,
) => {
  return {
    getRows: (params) => {
      console.log("[Datasource] - rows requested by grid: ", params.request);
      const response = server.getData(params.request);
      // adding delay to simulate real server call
      setTimeout(() => {
        if (response.success) {
          // call the success callback
          params.success({
            rowData: response.rows,
            rowCount: response.lastRow,
          });
        } else {
          // inform the grid request failed
          params.fail();
        }
      }, 200);
    },
  };
};

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    {
      headerName: "Group",
      field: "name",
      rowGroup: true,
      hide: true,
    },
    {
      field: "autoA",
      wrapText: true,
      autoHeight: true,
      aggFunc: "last",
    },
    {
      field: "autoB",
      wrapText: true,
      autoHeight: true,
      aggFunc: "last",
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
    };
  }, []);
  const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
    return {
      flex: 1,
      maxWidth: 200,
    };
  }, []);

  const onGridReady = useCallback((params: GridReadyEvent) => {
    // generate data for example
    const data = getData();
    // setup the fake server with entire dataset
    const fakeServer = new FakeServer(data);
    // create datasource with a reference to the fake server
    const datasource = getServerSideDatasource(fakeServer);
    // register the datasource with the grid
    params.api.setGridOption("serverSideDatasource", datasource);
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            autoGroupColumnDef={autoGroupColumnDef}
            rowModelType={"serverSide"}
            suppressAggFuncInHeader={true}
            onGridReady={onGridReady}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Auto Row Height Example](https://www.ag-grid.com/examples/server-side-model-row-height/auto-row-height/reactFunctionalTs/)

> **Note**
>
> Ensure `maxBlocksInCache` is not set when using auto row height.

## Changing Row Height

To dynamically set or restore row heights in the Server-Side Row Model, use `setRowHeight()` to apply custom heights to specific rows and `resetRowHeights()` to revert all rows to the values calculated by the `getRowHeight()` in Grid Options. See [Changing Row Height](https://www.ag-grid.com/react-data-grid/row-height/#rownodesetrowheightheight-and-apionrowheightchanged) for more.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `resetRowHeights` | `Function` |  |  | Tells the grid to recalculate the row heights. Modules (any of): [`ClientSideRowModelApiModule`](https://www.ag-grid.com/react-data-grid/modules/), [`ServerSideRowModelApiModule`](https://www.ag-grid.com/react-data-grid/modules/). |

The following example demonstrates this functionality:

- Clicking on a row sets its height to `100px` using `setRowHeight()`.
- Clicking the "Reset Row Heights" button resets all rows to their original heights using `resetRowHeights()`.

#### Reset Row Height Example

```tsx
("use client");

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import {
  AutoGroupColumnDef,
  ColDef,
  ColGroupDef,
  GetRowHeight,
  GetRowIdFunc,
  GridApi,
  GridOptions,
  GridReadyEvent,
  RowModelType,
} from "ag-grid-community";
import {
  ModuleRegistry,
  ServerSideRowModelApiModule,
  ServerSideRowModelModule,
  enableDevValidations,
} from "ag-grid-enterprise";
import { IOlympicDataWithId } from "./interfaces";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

const modules = [ServerSideRowModelModule, ServerSideRowModelApiModule];

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;

function createServerSideDatasource(server) {
  return {
    getRows: (params) => {
      console.log("[Datasource] - rows requested by grid: ", params.request);
      // get data for request from our fake server
      const response = server.getData(params.request);
      // simulating real server call with a 500ms delay
      setTimeout(() => {
        if (response.success) {
          // supply rows for requested block to grid
          params.success({
            rowData: response.rows,
            rowCount: response.lastRow,
          });
        } else {
          params.fail();
        }
      }, 500);
    },
  };
}

function createFakeServer(allData) {
  return {
    getData: (request) => {
      // take a slice of the total rows for requested block
      const rowsForBlock = allData.slice(request.startRow, request.endRow);
      // here we are pretending we don't know the last row until we reach it!
      const lastRow = getLastRowIndex(request, rowsForBlock);
      return {
        success: true,
        rows: rowsForBlock,
        lastRow: lastRow,
      };
    },
  };
}

function getLastRowIndex(request, results) {
  if (!results) return undefined;
  const currentLastRow = (request.startRow || 0) + results.length;
  // if on or after the last block, work out the last row, otherwise return 'undefined'
  return currentLastRow < (request.endRow || 0) ? currentLastRow : undefined;
}

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicDataWithId>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "90%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete", minWidth: 200 },
    { field: "age" },
    { field: "country", minWidth: 180 },
    { field: "year" },
    { field: "date", minWidth: 150 },
    { field: "gold" },
    { field: "silver" },
    { field: "bronze" },
    { field: "total" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
      // allow every column to be aggregated
      enableValue: true,
      sortable: false,
    };
  }, []);
  const getRowId = useCallback((p) => String(p.data?.id), []);
  const getRowHeight = useCallback((p) => {
    return 50 + 30 * Math.sin((p.data?.id ?? 0) / 5 - Math.PI / 2);
  }, []);
  const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
    return {
      minWidth: 200,
    };
  }, []);

  const onGridReady = useCallback((params: GridReadyEvent) => {
    fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
      .then((resp) => resp.json())
      .then((data: IOlympicDataWithId[]) => {
        // adding row id to data
        let idSequence = 0;
        data.forEach(function (item: { id: number }) {
          item.id = idSequence++;
        });
        // setup the fake server with entire dataset
        const fakeServer = createFakeServer(data);
        // create datasource with a reference to the fake server
        const datasource = createServerSideDatasource(fakeServer);
        // register the datasource with the grid
        params.api.setGridOption("serverSideDatasource", datasource);
      });
  }, []);

  const onRowClicked = useCallback((p) => {
    p.node.setRowHeight(100);
    p.api.onRowHeightChanged();
  }, []);

  const resetRowHeights = useCallback(() => {
    gridRef.current!.api.resetRowHeights();
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={{ height: "100%" }}>
          <button onClick={resetRowHeights}>Reset Row Heights</button>

          <div style={gridStyle}>
            <AgGridReact<IOlympicDataWithId>
              ref={gridRef}
              columnDefs={columnDefs}
              defaultColDef={defaultColDef}
              getRowId={getRowId}
              getRowHeight={getRowHeight}
              autoGroupColumnDef={autoGroupColumnDef}
              rowModelType={"serverSide"}
              onGridReady={onGridReady}
              onRowClicked={onRowClicked}
            />
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Reset Row Height Example](https://www.ag-grid.com/examples/server-side-model-row-height/resetting-row-height/reactFunctionalTs/)
