Notes let users attach comments to individual cells without storing note text in row data. Cells with notes are marked in the grid, note actions are available from the context menu, hovering a noted cell opens the built-in resizable note editor, and Shift + F2 opens or creates a note for the focused cell when notes are allowed.
Enabling Notes Copy Link
Notes are enabled by providing a notesDataSource. This lets you keep note state in a separate store and persist it independently of the row data.
Provide a data source to control where notes are stored and retrieved.
Can be updated to enable, disable, or replace Notes at runtime. |
<ag-grid-angular
[getRowId]="getRowId"
[notesDataSource]="notesDataSource"
/* other grid options ... */ />
const noteStore = new Map();
const noteKey = (rowId, colId) => `${rowId}::${colId}`;
this.getRowId = (params) => String(params.data.id);
this.notesDataSource = {
getNote: ({ rowNode, column }) => noteStore.get(noteKey(rowNode.id, column.getColId())),
setNote: ({ rowNode, column, note }) => {
const key = noteKey(rowNode.id, column.getColId());
if (note === undefined) {
noteStore.delete(key);
} else {
noteStore.set(key, note);
}
},
};The example above uses getRowId() so the note store can key notes consistently by row ID and column ID.
Notes Metadata Copy Link
Any note metadata, including author, createdAt, and updatedAt, is rendered exactly as provided by your datasource.
The built-in note editor only updates the note text. If notes created from the built-in UI should also include metadata, stamp it inside notesDataSource.setNote().
<ag-grid-angular
[notesDataSource]="notesDataSource"
/* other grid options ... */ />
const getCurrentUser = () => document.getElementById('current-user').value;
const getDisplayTimestamp = () => new Date().toLocaleString('en-GB');
this.notesDataSource = {
setNote: ({ rowNode, column, note }) => {
const key = noteKey(rowNode.id, column.getColId());
const existingNote = noteStore.get(key);
if (note === undefined) {
noteStore.delete(key);
} else {
noteStore.set(key, {
...existingNote,
...note,
author: getCurrentUser(),
createdAt: existingNote?.createdAt ?? getDisplayTimestamp(),
updatedAt: getDisplayTimestamp(),
});
}
},
}; Read-Only Notes Copy Link
Set CellNote.readOnly = true to make a note view-only. Read-only notes can still be opened from hover, the context menu, or Shift + F2, but they cannot be edited or removed through the built-in UI or the mutating Notes API calls.
noteStore.set(noteKey('3', 'country'), {
text: 'Check the latest federation naming guidance for this country.',
author: 'AG Grid',
updatedAt: '27 Mar 2026, 14:30',
readOnly: true,
});
Suppressing Note Actions Copy Link
Use colDef.suppressCellNoteActions to suppress built-in note actions for a column or specific row. Suppressed cells still allow existing notes to be viewed on hover and through getCellNote(), but add/edit/remove actions and note creation shortcuts are blocked.
<ag-grid-angular
[columnDefs]="columnDefs"
/* other grid options ... */ />
this.columnDefs = [
{ field: 'athlete' },
{ field: 'year', suppressCellNoteActions: true },
{ field: 'sport', suppressCellNoteActions: params => params.data?.sport === 'Swimming' },
]; Full Width Rows Copy Link
Notes also work with full width rows.
Even though a full width row is not rendered as individual cells, the datasource still receives a column. For standard full width rows, AG Grid resolves this to the first displayed column in the grid. In the example below, that column is athlete, so the seeded full width note is stored under the athlete colId.
noteStore.set(noteKey('2', 'athlete'), {
text: 'This note belongs to a full width row.',
});
If you are using embedded full width rows with pinned sections, the resolved note column comes from the row container being interacted with.
Feature Interaction Copy Link
When the ContextMenuModule is loaded, the default context menu adds note actions automatically. If you customise getContextMenuItems(), include the built-in cellNote item to keep the standard note actions:
<ag-grid-angular
[getContextMenuItems]="getContextMenuItems"
/* other grid options ... */ />
this.getContextMenuItems = () => ['cellNote', 'copy', 'export'];The built-in cellNote item expands based on the current cell state:
Add Cell Notewhen the cell has no note and note creation is allowed.Edit NoteandRemove Notewhen the existing note is editable.View Note, plus a disabledRemove Note, when the existing note is read-only.- Disabled note actions when the cell is suppressed. Existing suppressed notes still show
View Note.
Shift + F2 opens an existing note for the focused cell, or creates a new note if the cell allows notes and does not already have one. Plain F2 keeps the normal cell editing behaviour.
API Copy Link
Use the grid API to read, write, remove and refresh notes programmatically. This is useful when notes are edited from application UI outside the grid, or when the underlying note store changes directly. The API example also shows how to set readOnly on a note payload.
In the example above, clicking a cell selects it, the toolbar reads the current note with getCellNote(), updates or removes the selected note with setCellNote(), and calls refreshCellNotes() after mutating the backing store directly.
API Reference Copy Link
Return the current note for a cell. |
Set or remove the note for a cell.
Pass note: undefined to remove the note. |
Refresh note presence for the currently rendered cells. |
NotesDataSource Copy Link
Properties available on the NotesDataSource interface.
Initialise the data source so that the user can take a reference to the gridApi if needed. |
Return the note for the given cell. |
Set or clear the note for the given cell. |
Called by the grid when the data source is being disposed. |
CellNote Copy Link
string |
boolean |
string |
string |
string |
RefreshCellNotesParams Copy Link
IRowNode[] |
(string | Column)[] |