# Template gallery > A starter-templates dialog wired to localStorage for "recently used". Source: https://docs.docmosaic.com/docs/examples/templates `Editor.TemplateGallery` is the modal grid you show when a user starts blank. Pass it an array of `Document` snapshots and clicking one swaps the live document in a single undoable step. Pair it with `localStorage` to remember which templates a user has opened recently. ## Code ```tsx 'use client'; import { useMemo, useState } from 'react'; import { Editor, type TemplateGalleryItem } from '@docmosaic/react'; import { createDocument, createPage, type Document } from '@docmosaic/core'; import '@docmosaic/react/styles.css'; // Static templates ship with the app - keep these checked in. const STATIC_TEMPLATES: ReadonlyArray = [ { id: 'blank', name: 'Blank A4', document: createDocument({ name: 'Untitled', pageSize: 'A4', orientation: 'portrait' }), }, { id: 'letter', name: 'US Letter', document: createDocument({ name: 'Untitled', pageSize: 'LETTER', orientation: 'portrait' }), }, { id: 'landscape-a4', name: 'A4 landscape', document: createDocument({ name: 'Untitled', pageSize: 'A4', orientation: 'landscape' }), }, { id: 'three-pager', name: 'Three pages', document: { ...createDocument({ name: 'Three-pager', pageSize: 'A4', orientation: 'portrait' }), pages: [createPage(), createPage(), createPage()], totalPages: 3, } as Document, }, ]; function rememberRecent(id: string) { if (typeof window === 'undefined') return; const prev = JSON.parse(localStorage.getItem('recent-templates') ?? '[]') as string[]; const next = [id, ...prev.filter((p) => p !== id)].slice(0, 5); localStorage.setItem('recent-templates', JSON.stringify(next)); } export default function TemplatesEditor() { const [open, setOpen] = useState(true); const templates = useMemo(() => STATIC_TEMPLATES, []); return ( {open ? (

Pick a template

{ rememberRecent(t.id); setOpen(false); }} />
) : null}
); } ``` `onTemplateSelected` fires after the document swap. Use it for analytics, dialog close, or - like here - bumping the template id to the front of a recents list. The swap goes through `actions.loadDocument`, which is captured by the history timeline in uncontrolled mode. Users can `mod+z` back to the previous document. ## Try it ## Related - [Editor.TemplateGallery](/docs/primitives/template-gallery) - props - [Persisting templates](/docs/recipes/persisting-templates) - JSON serialisation patterns - [Save to a database](/docs/examples/save-to-database) - beyond localStorage