---
title: "Master / Detail - Nesting"
enterprise: true
framework: javascript
version: "36.1.0"
---

# Master / Detail - Nesting

It is possible to nest Master / Detail grids. There is no special configuration required to do this, you just configure another Detail Grid to also act as a Master Grid.

The following snippet illustrates how to achieve nesting by configuring Detail Grids to also act as Master Grids.

```js
// Level 3 (bottom level), Detail Grid only, no Master / Detail configuration
const gridOptionsLevel3 = {
    ...
}

// Level 2, configured to be a Master Grid and use Level 3 grid as Detail Grid,
const gridOptionsLevel2 = {
    masterDetail: true,
    detailCellRendererParams: {
        detailGridOptions: gridOptionsLevel3,
        getDetailRowData: function (params) {
            ...
        }
    }
    ...
}

// Level 1, configured to be a Master Grid and use Level 2 grid as Detail Grid,
const gridOptionsLevel1 = {
    masterDetail: true,
    detailCellRendererParams: {
        detailGridOptions: gridOptionsLevel2,
        getDetailRowData: function (params) {
            ...
        }
    }
    ...
}
```

Below shows a simple Master Detail setup with two levels of Master Detail. The example is kept short (few rows and columns) so as to focus on the nesting.

## Example

#### Nesting Master / Detail

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  IDetailCellRendererParams,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ColumnsToolPanelModule,
  ContextMenuModule,
  MasterDetailModule,
} from "ag-grid-enterprise";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  ColumnsToolPanelModule,
  MasterDetailModule,
  ColumnMenuModule,
  ContextMenuModule,
]);

const rowData = [
  {
    a1: "level 1 - 111",
    b1: "level 1 - 222",
    children: [
      {
        a2: "level 2 - 333",
        b2: "level 2 - 444",
        children: [
          { a3: "level 3 - 5551", b3: "level 3 - 6661" },
          { a3: "level 3 - 5552", b3: "level 3 - 6662" },
          { a3: "level 3 - 5553", b3: "level 3 - 6663" },
          { a3: "level 3 - 5554", b3: "level 3 - 6664" },
          { a3: "level 3 - 5555", b3: "level 3 - 6665" },
          { a3: "level 3 - 5556", b3: "level 3 - 6666" },
        ],
      },
    ],
  },
  {
    a1: "level 1 - 111",
    b1: "level 1 - 222",
    children: [
      {
        a2: "level 2 - 333",
        b2: "level 2 - 444",
        children: [
          { a3: "level 3 - 5551", b3: "level 3 - 6661" },
          { a3: "level 3 - 5552", b3: "level 3 - 6662" },
          { a3: "level 3 - 5553", b3: "level 3 - 6663" },
          { a3: "level 3 - 5554", b3: "level 3 - 6664" },
          { a3: "level 3 - 5555", b3: "level 3 - 6665" },
          { a3: "level 3 - 5556", b3: "level 3 - 6666" },
        ],
      },
    ],
  },
];

let gridApi: GridApi;

// level 1 grid options
const gridOptions: GridOptions = {
  rowData: rowData,
  columnDefs: [
    { field: "a1", cellRenderer: "agGroupCellRenderer" },
    { field: "b1" },
  ],
  defaultColDef: {
    flex: 1,
  },
  groupDefaultExpanded: 1,
  masterDetail: true,
  detailCellRendererParams: {
    // level 2 grid options
    detailGridOptions: {
      columnDefs: [
        { field: "a2", cellRenderer: "agGroupCellRenderer" },
        { field: "b2" },
      ],
      defaultColDef: {
        flex: 1,
      },
      groupDefaultExpanded: 1,
      masterDetail: true,
      detailRowHeight: 240,
      detailCellRendererParams: {
        // level 3 grid options
        detailGridOptions: {
          columnDefs: [
            { field: "a3", cellRenderer: "agGroupCellRenderer" },
            { field: "b3" },
          ],
          defaultColDef: {
            flex: 1,
          },
        },
        getDetailRowData: (params) => {
          params.successCallback(params.data.children);
        },
      } as IDetailCellRendererParams,
    },
    getDetailRowData: (params) => {
      params.successCallback(params.data.children);
    },
  } as IDetailCellRendererParams,
};

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);
```

[Live example: Nesting Master / Detail](https://www.ag-grid.com/examples/master-detail-nesting/nesting/typescript/)

## Example: Auto Height

The next example is identical to the previous except all the Detail Grids have property `detailRowAutoHeight=true`. Notice that this removes all vertical scrolls from all the Detail Grids, leaving just the main Master Grid with a vertical scroll.

#### Nesting Auto-Height

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  IDetailCellRendererParams,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ColumnsToolPanelModule,
  ContextMenuModule,
  MasterDetailModule,
} from "ag-grid-enterprise";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  ColumnsToolPanelModule,
  MasterDetailModule,
  ColumnMenuModule,
  ContextMenuModule,
]);

const rowData = [
  {
    a1: "level 1 - 111",
    b1: "level 1 - 222",
    children: [
      {
        a2: "level 2 - 333",
        b2: "level 2 - 444",
        children: [
          { a3: "level 3 - 5551", b3: "level 3 - 6661" },
          { a3: "level 3 - 5552", b3: "level 3 - 6662" },
          { a3: "level 3 - 5553", b3: "level 3 - 6663" },
          { a3: "level 3 - 5554", b3: "level 3 - 6664" },
          { a3: "level 3 - 5555", b3: "level 3 - 6665" },
          { a3: "level 3 - 5556", b3: "level 3 - 6666" },
        ],
      },
    ],
  },
  {
    a1: "level 1 - 111",
    b1: "level 1 - 222",
    children: [
      {
        a2: "level 2 - 333",
        b2: "level 2 - 444",
        children: [
          { a3: "level 3 - 5551", b3: "level 3 - 6661" },
          { a3: "level 3 - 5552", b3: "level 3 - 6662" },
          { a3: "level 3 - 5553", b3: "level 3 - 6663" },
          { a3: "level 3 - 5554", b3: "level 3 - 6664" },
          { a3: "level 3 - 5555", b3: "level 3 - 6665" },
          { a3: "level 3 - 5556", b3: "level 3 - 6666" },
        ],
      },
    ],
  },
];

let gridApi: GridApi;

// level 1 grid options
const gridOptions: GridOptions = {
  rowData: rowData,
  columnDefs: [
    { field: "a1", cellRenderer: "agGroupCellRenderer" },
    { field: "b1" },
  ],
  defaultColDef: {
    flex: 1,
  },
  groupDefaultExpanded: 1,
  masterDetail: true,
  detailRowAutoHeight: true,
  detailCellRendererParams: {
    // level 2 grid options
    detailGridOptions: {
      columnDefs: [
        { field: "a2", cellRenderer: "agGroupCellRenderer" },
        { field: "b2" },
      ],
      defaultColDef: {
        flex: 1,
      },
      groupDefaultExpanded: 1,
      masterDetail: true,
      detailRowHeight: 240,
      detailRowAutoHeight: true,
      detailCellRendererParams: {
        // level 3 grid options
        detailGridOptions: {
          columnDefs: [
            { field: "a3", cellRenderer: "agGroupCellRenderer" },
            { field: "b3" },
          ],
          defaultColDef: {
            flex: 1,
          },
        },
        getDetailRowData: (params) => {
          params.successCallback(params.data.children);
        },
      } as IDetailCellRendererParams,
    },
    getDetailRowData: (params) => {
      params.successCallback(params.data.children);
    },
  } as IDetailCellRendererParams,
};

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);
```

[Live example: Nesting Auto-Height](https://www.ag-grid.com/examples/master-detail-nesting/nesting-autoheight/typescript/)
