apps/docs/content/sdk-features/locked-shapes.mdx
Locked shapes can't be selected, moved, resized, edited, or deleted through normal interactions. Lock a shape when you want it to stay exactly where it is: background elements, reference images, or layout guides that shouldn't move while you work on other parts of the canvas.
Every shape has an isLocked boolean property. When true, the shape is protected from most modifications:
// Create a locked shape
editor.createShape({
type: 'geo',
x: 100,
y: 100,
isLocked: true,
props: { w: 200, h: 150, geo: 'rectangle' },
})
// Check if a shape is locked
const shape = editor.getShape(shapeId)
if (shape.isLocked) {
// Shape is locked
}
Use Editor#toggleLock to flip the lock state of shapes. If shapes have mixed lock states, they all become locked:
// Lock selected shapes
editor.toggleLock(editor.getSelectedShapeIds())
// Lock specific shapes by ID
editor.toggleLock([shapeId1, shapeId2])
When you lock shapes that were all previously unlocked, they automatically deselect. This prevents accidentally manipulating them while they're protected.
Locked shapes resist most operations:
| Operation | Behavior |
|---|---|
| Selection | Clicking a locked shape doesn't select it. Brush selection and Editor#selectAll skip locked shapes. |
| Movement | Pointer drags pass through locked shapes to the canvas. |
| Modification | Editor#updateShape ignores locked shapes, except for an update that unlocks them. |
| Deletion | Editor#deleteShapes and Editor#duplicateShapes skip locked shapes. |
| Grouping | Editor#groupShapes and Editor#ungroupShapes skip locked shapes. |
| Editing | Double-clicking a locked shape doesn't enter edit mode. |
Right-clicking a locked shape still selects it so the context menu can offer an unlock option. If you want left-click, brush, and scribble selection to include locked shapes too, set the selectLockedShapes option in TldrawOptions. The shapes stay protected from moves, edits, and deletes; selectAll still skips them.
Lock state inherits through the shape hierarchy. If a shape's ancestor is locked, the shape behaves as locked too. Check this with Editor#isShapeOrAncestorLocked:
// True if the shape or any of its parents is locked
const isProtected = editor.isShapeOrAncestorLocked(shape)
Locking a frame or group protects its children from pointer interactions and Editor#updateShapes without locking each shape individually. Bulk operations such as Editor#deleteShapes only check each shape's own isLocked, so a child of a locked frame can still be deleted programmatically.
Sometimes you need to modify locked shapes from code: migrations, admin tools, or automated operations. Wrap your operations in Editor#run with ignoreShapeLock: true:
editor.run(
() => {
// These operations affect locked shapes
editor.updateShape({ id: lockedShapeId, type: 'geo', x: 200 })
editor.deleteShapes([lockedShapeId])
},
{ ignoreShapeLock: true }
)
This bypasses the lock check for all operations inside the callback.
Even with ignoreShapeLock: true, some behaviors remain unchanged: locked shapes still can't be selected by clicking, pointer events still pass through to the canvas, and selectAll() still skips locked shapes. The flag affects Editor#updateShapes, Editor#deleteShapes, Editor#duplicateShapes, Editor#groupShapes, and Editor#ungroupShapes, not the selection and interaction model.
Some shapes have interactive content that should remain usable even when locked. Embed shapes (YouTube videos, Figma files, interactive maps) are a good example: you might want the embed locked in place but still playable or navigable.
ShapeUtils can override ShapeUtil#canEditWhileLocked (default false) to allow editing interactions on locked shapes. The built-in embed shape returns true unless its embed definition says otherwise:
class MyInteractiveShapeUtil extends ShapeUtil<MyShape> {
override canEditWhileLocked(shape: MyShape): boolean {
return true
}
}
When this returns true, Editor#canEditShape allows the shape to enter edit mode while locked, so users can interact with its content without moving or resizing it. It doesn't make the shape hit-testable on its own: with default options a double-click on a locked shape still passes through to the canvas. The shape enters edit mode when you call Editor#setEditingShape, or when the user selects it (for example with selectLockedShapes enabled) and presses Enter or double-clicks.
In the default tldraw UI, users can lock shapes through the context menu or the keyboard shortcut (Shift+L). Right-clicking a locked shape opens the context menu with an unlock option, and the main menu has an "Unlock all" action.
ignoreShapeLock.