Custom Renderers
Register custom cell and header renderers.
Custom renderers let you control DOM output while keeping ZenGrid’s virtualization model.
Cell Renderer
import type { CellRenderer } from '@zengrid/core';
export const progressRenderer: CellRenderer = { render(element, { value }) { const percent = Number(value); element.innerHTML = `<div class="bar"><span style="width: ${percent}%"></span></div>`; }, update(element, params) { this.render(element, params); }, destroy(element) { element.textContent = ''; },};grid.registerRenderer('progress', progressRenderer);
const columns: ColumnDef[] = [ { field: 'progress', header: 'Progress', width: 180, renderer: 'progress' },];Header Renderer
import type { HeaderRenderer } from '@zengrid/core';
export const compactHeaderRenderer: HeaderRenderer = { render(element, { column }) { element.textContent = String(column?.header ?? ''); element.className = 'compact-header'; }, update(element, params) { this.render(element, params); }, destroy(element) { element.textContent = ''; element.className = ''; },};grid.registerHeaderRenderer('compact', compactHeaderRenderer);
const columns: ColumnDef[] = [ { field: 'name', header: { text: 'Name', type: 'custom', renderer: 'compact' }, width: 220, },];Performance Rules
- Keep generated DOM stable and small.
- Avoid synchronous layout measurement in
render()andupdate(). - Clean up event listeners and element state in
destroy(). - Prefer CSS classes over inline style churn for repeated updates.
⚠ Warning
A slow renderer can make a virtualized grid feel slow. Test custom renderers with realistic row counts and scroll speed.