Save and restore layouts
Save and restore a layout
Section titled “Save and restore a layout”DashboardGrid computes positions when widgets move or resize. Connect onLayoutCommit to commands.applyLayoutSnapshot so React state reflects those positions before saving. Otherwise the saved state may differ from the visible layout.
- Save layout captures the full state in memory.
- Change width, or drag a widget title.
- Restore saved returns to the captured layout.
This example stores the snapshot in React memory. To persist across reloads, choose serializable data and write it to application storage.
import { useState } from 'react';import { DashboardGrid, useDashboardGrid, type DashboardWidget, type DashboardStateSnapshot } from 'comins-grid-layout';import 'gridstack/dist/gridstack.min.css';import 'comins-grid-layout/styles.css';
export default function GridDemo({ lang = 'ko' }: { lang?: string }) { const ko = lang === 'ko'; const initialWidgets: DashboardWidget[] = [ { id: 'overview', title: ko ? '프로젝트 개요' : 'Project overview', layout: { id: 'overview', x: 0, y: 0, w: 6, h: 2 } }, { id: 'activity', title: ko ? '최근 활동' : 'Recent activity', layout: { id: 'activity', x: 6, y: 0, w: 6, h: 2 } }, ]; const grid = useDashboardGrid({ initialColumns: 12, initialWidgets }); const [saved, setSaved] = useState<DashboardStateSnapshot | null>(null); const [status, setStatus] = useState(ko ? '제목을 드래그하여 배치를 바꿀 수 있습니다.' : 'Drag a title to rearrange the widgets.'); return <div className="demo grid-demo" data-demo="grid"> <div className="demo-toolbar"> <button onClick={() => { setSaved(grid.commands.serializeState()); setStatus(ko ? '현재 배치를 메모리에 저장했습니다.' : 'Saved this layout in memory.'); }}>{ko ? '배치 저장' : 'Save layout'}</button> <button onClick={() => { grid.commands.updateWidgetLayout('overview', { w: 3 }); setStatus(ko ? '첫 위젯의 너비를 변경했습니다.' : 'Changed the first widget width.'); }}>{ko ? '너비 변경' : 'Change width'}</button> <button disabled={!saved} onClick={() => { if (saved) { grid.commands.restoreLayout(saved); setStatus(ko ? '저장한 배치를 복원했습니다.' : 'Restored the saved layout.'); } }}>{ko ? '저장 상태 복원' : 'Restore saved'}</button> <button onClick={() => { grid.commands.resetLayout(); setSaved(null); setStatus(ko ? '초기 상태로 돌아왔습니다.' : 'Reset to the initial layout.'); }}>{ko ? '초기화' : 'Reset'}</button> </div> <DashboardGrid widgets={grid.widgets} columns={grid.columns} refreshKey={grid.refreshVersion} editable movable resizable showControls={false} engineOptions={{ cellHeight: 70, margin: 6, animate: false }} onLayoutCommit={grid.commands.applyLayoutSnapshot} renderWidget={(widget) => <div className="widget-content"><span className="widget-number">{widget.id === 'overview' ? '03' : '12'}</span><span>{widget.id === 'overview' ? (ko ? '함께 만드는 모듈' : 'Modules to build with') : (ko ? '열로 구성한 작업 공간' : 'Columns in your workspace')}</span></div>} /> <p role="status" className="demo-status">{status}</p> <details><summary>{ko ? '현재 레이아웃 JSON' : 'Current layout JSON'}</summary><pre data-layout>{JSON.stringify(grid.commands.serializeLayout(), null, 2)}</pre></details> </div>;}Which snapshot should you save?
Section titled “Which snapshot should you save?”| Method | Input / return | Purpose |
|---|---|---|
serializeLayout() |
Returns DashboardLayoutSnapshot |
Reads the current column count and widget geometry. |
serializeState() |
Returns DashboardStateSnapshot<TData> |
Includes widget data, maximize/minimize restore positions, and visited column layouts. |
applyLayoutSnapshot(snapshot) |
DashboardLayoutSnapshot → void |
Commits the grid geometry into state. |
restoreLayout(snapshot) |
DashboardStateSnapshotInput<TData> → void |
Replaces state with the saved snapshot. |
resetLayout(snapshot?) |
Geometry or state snapshot → void |
Resets to the initial state when omitted; otherwise replaces it with the snapshot. |
DashboardStateSnapshot
Section titled “DashboardStateSnapshot”| Field | Type | Meaning |
|---|---|---|
columns |
DashboardColumnCount |
Current column count |
widgets |
DashboardWidget<TData>[] |
Current widgets, geometry, data, and state |
previousLayouts |
Record<DashboardWidgetId, DashboardWidgetLayout> |
Geometry to restore from maximize/minimize |
layoutsByColumn |
DashboardLayoutsByColumn |
Cached layouts for visited column counts |
DashboardLayoutSnapshot.widgets is DashboardWidgetLayout[], not complete widgets. The two snapshots are not interchangeable.
Restore contract
Section titled “Restore contract”For backward compatibility, restoreLayout accepts inputs without previousLayouts or layoutsByColumn. When the active column cache differs from top-level state, top-level widgets and previousLayouts take priority. Outside a React reducer, the pure serializeDashboardState helper is also available.
Storage, schema migration, and server synchronization belong to the consumer application. Validate external JSON types, IDs, geometry, and business data before restoring. TypeScript annotations are not runtime JSON validation.
Search terms
Section titled “Search terms”Save layout, persist state, restore, persistence, serializeState, restoreLayout.