---
title: "Row Grouping - Group Rows"
enterprise: true
framework: react
version: "36.1.0"
---

# Row Grouping - Group Rows

Full width group rows can be used to represent the group structure in the grid.

#### Enabling Group Rows

```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 {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ICellRendererParams,
  ModuleRegistry,
  RowGroupingDisplayType,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [ClientSideRowModelModule, RowGroupingModule];

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: "athlete" },
    { field: "sport" },
    { field: "total" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            groupDisplayType={"groupRows"}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Enabling Group Rows](https://www.ag-grid.com/examples/grouping-group-rows/enabling-group-rows/reactFunctionalTs)

## Enabling Group Rows

The example above demonstrates that both `country` and `year` are grouped. No group column is generated, instead using full width rows to display the group value cells.

Group Rows can be enabled by setting the `groupDisplayType` grid option to `"groupRows"` as shown below:

```jsx
const groupDisplayType = 'groupRows';

<AgGridReact groupDisplayType={groupDisplayType} />
```

## Cell Component

The group rows use the `agGroupCellRenderer` component to display the group information, as well as the chevron control for expanding and collapsing rows.

This can be configured with several [Group Renderer Properties](https://www.ag-grid.com/react-data-grid/grouping-group-rows/#configurable-options) using the `groupRowRendererParams` grid option.

The example below removes the row count. Checkboxes are enabled for row selection with the `checkboxLocation` property, and `groupSelects` is set to `'descendants'` so that selecting a group row also selects all of its children.

#### Group Cell Renderer Configuration

```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 {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  RowGroupingDisplayType,
  RowSelectionModule,
  RowSelectionOptions,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [
  RowSelectionModule,
  ClientSideRowModelModule,
  RowGroupingModule,
];

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 },
    { field: "athlete" },
    { field: "year" },
    { field: "sport" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
    };
  }, []);
  const groupRowRendererParams = useMemo(() => {
    return {
      suppressCount: true,
    };
  }, []);
  const rowSelection = useMemo<
    RowSelectionOptions | "single" | "multiple"
  >(() => {
    return {
      mode: "multiRow",
      groupSelects: "descendants",
      checkboxLocation: "autoGroupColumn",
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            groupRowRendererParams={groupRowRendererParams}
            rowSelection={rowSelection}
            groupDisplayType={"groupRows"}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Group Cell Renderer Configuration](https://www.ag-grid.com/examples/grouping-group-rows/renderer-config-group-cell/reactFunctionalTs)

The example above demonstrates the following configuration:

```jsx
const [columnDefs, setColumnDefs] = useState([
    { field: 'total', rowGroup: true, cellRenderer: CustomMedalCellRenderer },
    // ... other column definitions
]);
const groupRowRendererParams = {
    suppressCount: true,
};
const rowSelection = useMemo(() => { 
	return {
        mode: 'multiRow',
        groupSelects: 'descendants',
        checkboxLocation: 'autoGroupColumn',
    };
}, []);

<AgGridReact
    columnDefs={columnDefs}
    groupRowRendererParams={groupRowRendererParams}
    rowSelection={rowSelection}
/>
```

### Configurable Options

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `suppressPadding` | `boolean` |  |  | Set to `true` to not include any padding (indentation) in the child rows. |
| `suppressDoubleClickExpand` | `boolean` |  |  | Set to `true` to suppress expand on double click. |
| `suppressEnterExpand` | `boolean` |  |  | Set to `true` to suppress expand on ↵ Enter |
| `totalValueGetter` | `string \| TotalValueGetterFunc` |  |  | The value getter for the total row text. Can be a function or expression. |
| `suppressCount` | `boolean` |  |  | If `true`, count is not displayed beside the name. |
| `innerRenderer` | `any` |  |  | The renderer to use for inside the cell (after grouping functions are added) |
| `innerRendererParams` | `any` |  |  | Additional params to customise to the `innerRenderer`. |
| `innerRendererSelector` | `CellRendererSelectorFunc` |  |  | Callback to enable different innerRenderers to be used based of value of params. |

### Checkbox Selection

The `agGroupCellRenderer` can be configured to show checkboxes for row selection. Setting the [Row Selection](https://www.ag-grid.com/react-data-grid/row-selection/) `checkboxLocation` property to `'autoGroupColumn'` does not hide the [Checkbox Column](https://www.ag-grid.com/react-data-grid/row-selection-single-row/#customising-the-checkbox-column) but does prevent any columns configured with `agGroupCellRenderer` from showing checkboxes.

Setting `groupSelects` to `'descendants'` causes selecting a group row to also select all of its children.

#### Group Cell Renderer Checkbox Selection

```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 {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  RowGroupingDisplayType,
  RowSelectionModule,
  RowSelectionOptions,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [
  RowSelectionModule,
  ClientSideRowModelModule,
  RowGroupingModule,
];

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 },
    { field: "athlete" },
    { field: "year" },
    { field: "sport" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
    };
  }, []);
  const rowSelection = useMemo<
    RowSelectionOptions | "single" | "multiple"
  >(() => {
    return {
      mode: "multiRow",
      groupSelects: "descendants",
      selectAll: "all",
      checkboxLocation: "autoGroupColumn",
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            groupDisplayType={"groupRows"}
            rowSelection={rowSelection}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Group Cell Renderer Checkbox Selection](https://www.ag-grid.com/examples/grouping-group-rows/renderer-config-checkbox/reactFunctionalTs)

The example above demonstrates the following configuration:

```jsx
const rowSelection = useMemo(() => { 
	return {
        mode: 'multiRow',
        groupSelects: 'descendants',
        selectAll: 'all',
        checkboxLocation: 'autoGroupColumn',
    };
}, []);

<AgGridReact rowSelection={rowSelection} />
```

### Custom Inner Renderer

When using the group cell renderer, the `agGroupCellRenderer` component will inherit the grouped columns renderer and display this inside of the group cell, adjacent to any configured checkboxes, cell count, and the expand/collapse chevron control.

This inner renderer can be overridden with a [Custom Cell Component](https://www.ag-grid.com/react-data-grid/component-cell-renderer/) by setting the `innerRenderer` and `innerRendererParams` properties on the `groupRowRendererParams` grid option.

#### Group Cell Renderer Configuration

```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 "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  RowGroupingDisplayType,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import CustomMedalCellRenderer from "./customMedalCellRenderer.tsx";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [ClientSideRowModelModule, RowGroupingModule];

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

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete" },
    { field: "year" },
    { field: "sport" },
    { field: "total", rowGroup: true },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
    };
  }, []);
  const groupRowRendererParams = useMemo(() => {
    return {
      suppressCount: true,
      innerRenderer: CustomMedalCellRenderer,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            groupRowRendererParams={groupRowRendererParams}
            groupDisplayType={"groupRows"}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Group Cell Renderer Configuration](https://www.ag-grid.com/examples/grouping-group-rows/renderer-config-inner/reactFunctionalTs)

The example above uses the following configuration to provide a custom inner renderer to the group column:

```jsx
const autoGroupColumnDef = useMemo(() => { 
	return {
        cellRendererParams: {
            innerRenderer: CustomMedalCellRenderer,
        },
    };
}, []);

<AgGridReact autoGroupColumnDef={autoGroupColumnDef} />
```

### Custom Cell Renderer

The Group Cell Renderer can be entirely replaced with a [Custom Cell Component](https://www.ag-grid.com/react-data-grid/component-cell-renderer/) by setting the `groupRowRenderer` grid option.

#### Custom Group Cell Renderer

```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 "./styles.css";
import {
  CellDoubleClickedEvent,
  CellKeyDownEvent,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  RowGroupingDisplayType,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import CustomGroupCellRenderer from "./customGroupCellRenderer.tsx";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [ClientSideRowModelModule, RowGroupingModule];

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

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    {
      field: "country",
      hide: true,
      rowGroup: true,
    },
    {
      field: "year",
      hide: true,
      rowGroup: true,
    },
    {
      field: "athlete",
    },
    {
      field: "sport",
    },
    {
      field: "total",
      aggFunc: "sum",
    },
  ]);
  const groupRowRenderer = useCallback(CustomGroupCellRenderer, []);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 120,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/small-olympic-winners.json",
  );

  const onCellDoubleClicked = useCallback(
    (params: CellDoubleClickedEvent<IOlympicData, any>) => {
      if (params.colDef.showRowGroup) {
        params.node.setExpanded(!params.node.expanded);
      }
    },
    [],
  );

  const onCellKeyDown = useCallback(
    (params: CellKeyDownEvent<IOlympicData, any>) => {
      if (!("colDef" in params)) {
        return;
      }
      if (!(params.event instanceof KeyboardEvent)) {
        return;
      }
      if (params.event.code !== "Enter") {
        return;
      }
      if (params.colDef.showRowGroup) {
        params.node.setExpanded(!params.node.expanded);
      }
    },
    [],
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            groupRowRenderer={groupRowRenderer}
            defaultColDef={defaultColDef}
            groupDisplayType={"groupRows"}
            onCellDoubleClicked={onCellDoubleClicked}
            onCellKeyDown={onCellKeyDown}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Custom Group Cell Renderer](https://www.ag-grid.com/examples/grouping-group-rows/renderer-config-custom/reactFunctionalTs)

The example above sets a custom cell renderer using the following configuration:

```jsx
const groupRowRenderer = CustomGroupCellRenderer;

<AgGridReact groupRowRenderer={groupRowRenderer} />
```
