--- title: Options created_at: 12/25/2025 updated_at: 12/25/2025 keywords: - options - TldrawOptions - configuration - settings - defaults status: published date: 12/25/2025 readability: 9 voice: 9 completeness: 9 accuracy: 10 notes: '' --- The tldraw editor accepts two kinds of configuration: **editor options** for core behavior (timing, limits, performance) and **component props** for UI, persistence, and content handling. Editor options are fixed after initialization; component props configure how the editor sets up. ## Editor options The `options` prop accepts a `Partial<`[TldrawOptions](?)`>` object that configures core editor behavior: limits like maximum pages and shapes, timing for interactions and animations, sizing for handles and hit testing, and feature toggles. Options are set once when the editor initializes and cannot change afterward. Pass a partial options object to override specific values; everything else uses the defaults. ```tsx import { Tldraw, TldrawOptions } from 'tldraw' const options: Partial = { maxPages: 3, maxShapesPerPage: 1000, } function App() { return } ``` ## Reading options at runtime After the editor initializes, access options through `editor.options`: ```typescript const maxPages = editor.options.maxPages const animationDuration = editor.options.animationMediumMs ``` The options object is readonly. Attempting to modify it has no effect and TypeScript will flag the error. ## Editor option categories ### Limits Cap shape, page, and file counts: | Option | Default | Description | | ------------------ | ------- | ----------------------------------- | | `maxShapesPerPage` | 4000 | Maximum shapes allowed on one page | | `maxPages` | 40 | Maximum pages in a document | | `maxFilesAtOnce` | 100 | Maximum files to handle in one drop | Setting `maxPages` to 1 effectively disables multi-page functionality and removes the page menu from the UI. ### Interaction timing Configure how the editor interprets user input timing: | Option | Default | Description | | ----------------------- | ------- | ------------------------------------------------- | | `doubleClickDurationMs` | 450 | Maximum interval for double-click detection | | `multiClickDurationMs` | 200 | Window for triple- and quadruple-click detection | | `longPressDurationMs` | 500 | Duration to trigger long press | | `animationMediumMs` | 320 | Duration for camera animations (zoom, pan to fit) | ### Drag detection Control when pointer movement becomes a drag operation: | Option | Default | Description | | ----------------------------- | ------- | ---------------------------------------- | | `dragDistanceSquared` | 16 | Distance² threshold for mouse drag (4px) | | `coarseDragDistanceSquared` | 36 | Distance² threshold for touch drag (6px) | | `uiDragDistanceSquared` | 16 | Distance² for UI element drag (4px) | | `uiCoarseDragDistanceSquared` | 625 | Distance² for touch UI drag (25px) | Values are squared to avoid computing square roots during drag detection. The larger touch thresholds prevent accidental drags on mobile devices. The UI thresholds govern dragging a tool out of the toolbar. A drag starts once the pointer has left the toolbar, so they matter only for presses that begin near its edge. ### Handle and hit testing Configure selection handles and click target areas: | Option | Default | Description | | --------------------- | ------- | --------------------------------------------- | | `handleRadius` | 12 | Radius of selection handles | | `coarseHandleRadius` | 20 | Handle radius for touch input | | `hitTestMargin` | 3 | Additional margin around shapes for hit tests | | `coarseHitTestMargin` | 4 | Hit test margin when using a coarse pointer | ### Edge scrolling Configure auto-scroll behavior when dragging near viewport edges: | Option | Default | Description | | ------------------------ | ------- | ------------------------------------------------------------------------ | | `edgeScrollDelay` | 200 | Milliseconds before scroll starts | | `edgeScrollEaseDuration` | 200 | Milliseconds to accelerate to full speed | | `edgeScrollSpeed` | 25 | Base scroll speed, multiplied by the user's edge scroll speed preference | | `edgeScrollDistance` | 8 | Width of the edge scroll trigger zone | | `coarsePointerWidth` | 12 | Pointer width used to widen the trigger zone for touch | See [Edge scrolling](/sdk-features/edge-scrolling) for details on how these options affect behavior. ### Camera Control camera movement and viewport behavior: | Option | Default | Description | | ------------------------- | ------------------------ | --------------------------------------------------------------------------------- | | `cameraSlideFriction` | 0.09 | Friction applied to camera momentum | | `cameraMovingTimeoutMs` | 64 | Time before camera is considered stopped | | `followChaseViewportSnap` | 2 | Snap threshold when following collaborators | | `spacebarPanning` | true | Enable spacebar to activate pan mode | | `rightClickPanning` | true | Enable right-click and drag to pan the camera | | `zoomToFitPadding` | 128 | Padding around content when zooming to fit bounds | | `camera` | `DEFAULT_CAMERA_OPTIONS` | Initial [TLCameraOptions](?); change at runtime with [Editor#setCameraOptions](?) | | `deepLinks` | undefined | Sync camera state with the URL: `true` or a [TLDeepLinkOptions](?) object | The `camera` and `deepLinks` options replace the deprecated `cameraOptions` and `deepLinks` props on the component. See [Camera](/sdk-features/camera) for the camera options. ### Snapping | Option | Default | Description | | -------------------- | ------- | ---------------------------------------------------------------------------------------------- | | `snapThreshold` | 8 | Distance in pixels at which snapping engages | | `selectLockedShapes` | false | Allow left-clicking and brushing to select locked shapes (they still can't be moved or edited) | ### Collaboration Configure timing for collaborator presence: | Option | Default | Description | | ------------------------------- | ------- | ----------------------------------------- | | `collaboratorInactiveTimeoutMs` | 60000 | Time before collaborator marked inactive | | `collaboratorIdleTimeoutMs` | 3000 | Time before collaborator marked idle | | `collaboratorCheckIntervalMs` | 1200 | Interval for checking collaborator status | ### Export Configure image and SVG export behavior: | Option | Default | Description | | --------------------------- | -------- | ---------------------------------------- | | `defaultSvgPadding` | 32 | Padding around exported SVG content | | `maxExportDelayMs` | 5000 | Maximum wait time for export completion | | `flattenImageBoundsExpand` | 64 | Expansion when flattening images | | `flattenImageBoundsPadding` | 16 | Padding when flattening images | | `exportProvider` | Fragment | React provider wrapping exported content | The `exportProvider` option wraps exported content in a React component. Use this when your custom shapes depend on context providers that must be present during rendering: ```tsx const options: Partial = { exportProvider: ({ children }) => {children}, } ``` ### Grid Configure the alignment grid: ```typescript gridSteps: [ { min: -1, mid: 0.15, step: 64 }, { min: 0.05, mid: 0.375, step: 16 }, { min: 0.15, mid: 1, step: 4 }, { min: 0.7, mid: 2.5, step: 1 }, ] ``` Each entry defines a grid step size based on zoom level. The `min` and `mid` values define the zoom range where the `step` applies. Zoomed out, the grid uses larger steps; zoomed in, finer ones. ### Performance Options that affect rendering performance: | Option | Default | Description | | ---------------------------- | -------- | ---------------------------------------- | | `debouncedZoom` | true | Use cached zoom while camera is moving | | `debouncedZoomThreshold` | 500 | Shape count threshold for debounced zoom | | `maxFontsToLoadBeforeRender` | Infinity | Fonts to load before showing canvas | | `textShadowLod` | 0.35 | Zoom threshold for text shadow rendering | When `debouncedZoom` is enabled and the page has more shapes than `debouncedZoomThreshold`, the editor returns a cached zoom level during camera movement. This reduces re-renders of complex documents. ### UI and features | Option | Default | Description | | -------------------------------- | --------- | ------------------------------------------------------------------------------------------------------- | | `createTextOnCanvasDoubleClick` | true | Create text shape on empty canvas double-click | | `enableToolbarKeyboardShortcuts` | true | Enable number keys (1-9, 0) for toolbar items | | `actionShortcutsLocation` | 'swap' | Where the quick actions (undo, redo, delete, duplicate) render | | `tooltipDelayMs` | 700 | Delay before showing tooltips | | `laserDelayMs` | 1200 | Duration laser pointer remains visible | | `laserFadeoutMs` | 500 | Duration for laser pointer fadeout animation | | `quickZoomPreservesScreenBounds` | true | Whether quick zoom brush keeps viewport scale | | `branding` | undefined | App name for accessibility labels | | `nonce` | undefined | CSP nonce for inline styles | | `adjacentShapeMargin` | 10 | Gap used when placing adjacent notes, duplicating, stacking, and packing shapes | | `text` | `{}` | [TLTextOptions](?): TipTap configuration and font handling (replaces the deprecated `textOptions` prop) | The `actionShortcutsLocation` option controls where the quick actions render: - `'menu'` - Always in the menu panel - `'toolbar'` - Always in the toolbar - `'swap'` - In the menu panel on tablet-sized screens and up, in the toolbar below that ### Asset handling | Option | Default | Description | | --------------------------------- | ------- | ------------------------------------------------- | | `temporaryAssetPreviewLifetimeMs` | 180000 | How long temporary asset previews persist (3 min) | ### Clipboard hooks These callbacks let you intercept and customize clipboard operations: | Option | Description | | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `onBeforeCopyToClipboard` | Called before content is written to the clipboard during copy or cut. Return modified `TLContent` to transform, `false` to cancel, or `void` to pass through. | | `onBeforePasteFromClipboard` | Called before pasted content is processed and shapes are created. Return `false` to cancel, a modified content object to transform, or `void` to pass through. Only fires for paste, not file drops. | | `onClipboardPasteRaw` | Called first for keyboard and menu paste, before tldraw parses clipboard data. Return `false` to cancel default paste handling, or `void` to continue. | See [Clipboard](/sdk-features/clipboard) for more details on clipboard operations. ### Drop handling | Option | Description | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | `experimental__onDropOnCanvas` | Called when content is dropped on the canvas. Receives the page position and drag event. Return `true` to prevent default drop handling. | ## Default values The [defaultTldrawOptions](?) export provides all default values: ```typescript import { defaultTldrawOptions } from 'tldraw' console.log(defaultTldrawOptions.maxPages) // 40 ``` Use this to check defaults or spread into your own options: ```typescript const options: Partial = { ...defaultTldrawOptions, maxPages: 10, } ``` ## Tldraw component props The `` component accepts additional props beyond those available on ``. These props configure the UI layer, external content handling, and other features that the full SDK provides. ### UI configuration | Prop | Type | Description | | ------------- | ----------------------- | -------------------------------------------------- | | `hideUi` | `boolean` | Hide all UI elements, showing only the canvas | | `forceMobile` | `boolean` | Force mobile breakpoints regardless of screen size | | `overrides` | `TLUiOverrides` | Override actions, tools, and translations | | `onUiEvent` | `TLUiEventHandler` | Callback for UI interaction events | | `components` | `TLComponents` | Override or disable UI and canvas components | | `assetUrls` | `TLUiAssetUrlOverrides` | Custom URLs for fonts, icons, and other UI assets | The `hideUi` prop is useful when building custom interfaces around the canvas: ```tsx function CustomEditor() { return ( ) } ``` ### External content handling These props control how the editor handles dropped or pasted files: | Prop | Default | Description | | ------------------------ | ------------------------------- | ------------------------------------------------------- | | `maxImageDimension` | 5000 | Maximum width/height for images (larger images resized) | | `maxAssetSize` | 10485760 | Maximum file size in bytes (10 MB) | | `acceptedImageMimeTypes` | `DEFAULT_SUPPORTED_IMAGE_TYPES` | Allowed image MIME types | | `acceptedVideoMimeTypes` | `DEFAULT_SUPPORT_VIDEO_TYPES` | Allowed video MIME types | ```tsx function App() { return ( ) } ``` ### Embeds Customize which embed types the editor recognizes using `EmbedShapeUtil.configure()`: ```tsx import { Tldraw, EmbedShapeUtil, DEFAULT_EMBED_DEFINITIONS } from 'tldraw' const shapeUtils = [ EmbedShapeUtil.configure({ embedDefinitions: [ ...DEFAULT_EMBED_DEFINITIONS, { type: 'custom-video', title: 'Custom Video', hostnames: ['videos.example.com'], width: 560, height: 315, doesResize: true, toEmbedUrl: (url) => url.replace('/watch/', '/embed/'), fromEmbedUrl: (url) => url.replace('/embed/', '/watch/'), }, ], }), ] function App() { return } ``` See [Embed shape](/sdk-features/embed-shape#Custom-embed-definitions) for the full embed definition API. ### Editor setup These props configure how the editor initializes: | Prop | Type | Description | | -------------------- | ------------------------------------------------------- | ------------------------------------------------------- | | `autoFocus` | `boolean` | Automatically focus the editor on mount | | `initialState` | `string` | Initial tool state (`` defaults to `'select'`) | | `shapeUtils` | `TLAnyShapeUtilConstructor[]` | Custom shape utilities | | `bindingUtils` | `TLAnyBindingUtilConstructor[]` | Custom binding utilities | | `overlayUtils` | `TLAnyOverlayUtilConstructor[]` | Custom [overlay utilities](/sdk-features/overlay-utils) | | `tools` | `TLStateNodeConstructor[]` | Custom tools | | `onMount` | `TLOnMountHandler` | Callback when editor mounts | | `getShapeVisibility` | `(shape, editor) => 'visible' \| 'hidden' \| 'inherit'` | Conditionally hide shapes | | `user` | `TLCurrentUser` | Current user information | | `colorScheme` | `'light' \| 'dark' \| 'system'` | Color scheme (defaults to `'light'`) | | `licenseKey` | `string` | License key to remove watermark | | `themes` | `Partial` | Named themes for the editor | | `initialTheme` | `TLThemeId` | Initially active theme (defaults to `'default'`) | | `locale` | `string` | UI locale; overrides browser and user preferences | The `cameraOptions`, `deepLinks`, `textOptions`, and `embeds` props are deprecated. Use `options.camera`, `options.deepLinks`, `options.text`, and `EmbedShapeUtil.configure` instead. The `getShapeVisibility` callback lets you conditionally hide shapes based on their properties: ```tsx { // Hide shapes marked as hidden in meta if (shape.meta.hidden) return 'hidden' // Force-show shapes regardless of parent visibility if (shape.meta.alwaysVisible) return 'visible' // Default: visible unless parent is hidden return 'inherit' }} /> ``` ### Store configuration When not providing your own store, these props configure automatic store creation: | Prop | Type | Description | | ---------------- | --------------------- | ----------------------------------------------------- | | `persistenceKey` | `string` | Key for IndexedDB persistence (enables local storage) | | `sessionId` | `string` | Session identifier for persistence | | `snapshot` | `TLEditorSnapshot` | Initial document state | | `migrations` | `MigrationSequence[]` | Additional migrations for custom schemas | ```tsx function App() { return } ``` Alternatively, provide your own store with the `store` prop for full control over data management. ## Examples - **[Editor options](https://github.com/tldraw/tldraw/tree/main/apps/examples/src/examples/configuration/custom-options)** - Override default options like max pages and animation speed. - **[Disable pages](https://github.com/tldraw/tldraw/tree/main/apps/examples/src/examples/configuration/disable-pages)** - Set `maxPages` to 1 to create a single-page editor.