--- title: Text shape created_at: 1/31/2026 updated_at: 1/31/2026 keywords: - text - text shape - text tool - autoSize - fixed width - wrapping - textAlign - alignment - font - rich text - editing status: published date: 1/31/2026 --- The text shape displays formatted text on the canvas. It has two modes: auto-size, where the shape grows to fit its content, and fixed-width, where text wraps at a set width. The text tool creates text shapes. See [TextShapeUtil](?) and [TLTextShape](?). ## Auto-size vs fixed-width Text shapes operate in two modes controlled by the `autoSize` property: | Mode | Behavior | Use case | | ----------- | ---------------------------------------------------------------- | ----------------------------------------- | | Auto-size | Shape width expands to fit content; text never wraps | Labels, titles, short annotations | | Fixed-width | Text wraps at the shape's width boundary; height grows as needed | Paragraphs, longer descriptions, callouts | ### Auto-size mode When `autoSize` is true (the default), the shape grows to fit its text. The shape widens as you type, and text never wraps unless you press Enter. ```tsx import { toRichText } from 'tldraw' editor.createShape({ type: 'text', x: 100, y: 100, props: { richText: toRichText('This text will never wrap'), autoSize: true, }, }) ``` Which edge stays put as an auto-sized shape grows depends on `textAlign`: with `start` the left edge stays fixed and the shape grows to the right, with `middle` the center stays fixed, and with `end` the right edge stays fixed. ### Fixed-width mode When `autoSize` is false, the shape uses a fixed width specified by the `w` property. Text wraps when it reaches this boundary, and the shape grows vertically to accommodate additional lines. ```tsx editor.createShape({ type: 'text', x: 100, y: 100, props: { richText: toRichText('This text will wrap when it reaches the specified width'), autoSize: false, w: 200, // Width in pixels }, }) ``` To convert an auto-sized shape to fixed-width, drag its left or right edge handle. The shape switches to fixed-width mode and keeps that width as you type. ## Text alignment The `textAlign` property controls horizontal text alignment: | Value | Description | | -------- | ---------------------------------------------- | | `start` | Left-aligned (or right-aligned in RTL locales) | | `middle` | Center-aligned | | `end` | Right-aligned (or left-aligned in RTL locales) | ```tsx editor.createShape({ type: 'text', x: 100, y: 100, props: { richText: toRichText('Centered text'), textAlign: 'middle', autoSize: false, w: 300, }, }) ``` Text shapes always align vertically to the middle of the shape's geometry. ## Creating text with the text tool The text tool (`T` key) creates text shapes in two ways. Double-clicking empty canvas with the select tool also creates an auto-sized text shape. ### Click to create auto-sized text Click anywhere on the canvas to create an auto-sized text shape. The shape appears centered at your click position and immediately enters edit mode. Start typing to add content. ### Drag to create fixed-width text Hold and drag horizontally to create a fixed-width text shape. Once the pointer has been down for at least 150ms and the horizontal drag exceeds about six times the base drag distance (larger for coarse pointers, scaled by zoom), the tool creates a fixed-width shape at that width and hands off to the select tool's resize state. Keep dragging to adjust the width, then release to start editing. Quick, short drags create auto-sized shapes instead. ### Tool shortcuts | Action | Result | | -------------------------- | -------------------------------------------- | | **Click** | Create auto-sized text at click position | | **Drag horizontally** | Create fixed-width text with dragged width | | **Enter** (shape selected) | Switch to the select tool and edit the shape | | **Escape** | Exit text tool, return to select tool | | **Cmd/Ctrl+Enter** | Confirm text and exit edit mode | ## Editing text Double-click a text shape or press Enter while it's selected to enter edit mode. The shape displays a cursor and you can type, select, and format text using the rich text editor. Text shapes use the same [rich text](/sdk-features/rich-text) system as notes, geo shapes, and arrow labels. You get bold, italic, code, highlighting, and more through keyboard shortcuts or the rich text toolbar. ### Empty text deletion When editing ends, the shape deletes itself if its text is empty or only trailing whitespace. This keeps invisible shapes off the canvas. ## Scaling and resize Text shapes support two resize behaviors: ### Aspect-ratio locked scaling Dragging any handle other than the left or right edges scales the whole shape proportionally. The `scale` property tracks this multiplier. ```tsx // A text shape at 2x scale editor.createShape({ type: 'text', props: { richText: toRichText('Scaled up'), scale: 2, }, }) ``` ### Width adjustment Dragging the left or right edge handles adjusts only the width. For auto-sized shapes, this converts them to fixed-width mode. For already fixed-width shapes, this changes where text wraps. ## Dynamic resize mode When `editor.user.getIsDynamicResizeMode()` is true, new text shapes are created with a scale inversely proportional to the current zoom level. At 200% zoom, new shapes get `scale: 0.5`; at 50% zoom, they get `scale: 2`. This keeps text visually consistent regardless of your zoom level when creating it. Use [Editor#getResizeScaleFactor](?) to get the same value: ```tsx const scale = editor.getResizeScaleFactor() ``` ## Arrow bindings Arrows can bind to text shapes just like other shapes. When an arrow with no arrowhead binds to a text shape, the shape's geometry is widened by `extraArrowHorizontalPadding` on each side (10 by default) so the bare line ends short of the glyphs. Arrows with arrowheads bind to the unpadded box. See [Configuration](#configuration) to change the padding. ## Text outline Text shapes display an outline in the canvas background color, which keeps text readable when it overlaps other shapes. The outline uses CSS `text-shadow` and is on by default. Safari skips it because `text-shadow` performs poorly there. Turn it off with the `showTextOutline` option (see [Configuration](#configuration)). ## Properties | Property | Type | Default | Description | | ----------- | ------------------------- | --------- | ----------------------------------------------- | | `richText` | `TLRichText` | empty | Text content with formatting | | `color` | `TLDefaultColorStyle` | `'black'` | Text color | | `size` | `TLDefaultSizeStyle` | `'m'` | Font size preset (`s`, `m`, `l`, `xl`) | | `font` | `TLDefaultFontStyle` | `'draw'` | Font family (`draw`, `sans`, `serif`, `mono`) | | `textAlign` | `TLDefaultTextAlignStyle` | `'start'` | Horizontal alignment (`start`, `middle`, `end`) | | `autoSize` | `boolean` | `true` | When true, shape resizes to fit content | | `w` | `number` | `8` | Width when autoSize is false | | `scale` | `number` | `1` | Scale factor applied to the shape | ## Configuration | Option | Type | Default | Description | | ----------------------------- | --------- | ------- | ------------------------------------------------------------------------ | | `extraArrowHorizontalPadding` | `number` | `10` | Extra horizontal padding when an arrow without an arrowhead binds | | `showTextOutline` | `boolean` | `true` | Display text outline for readability (skipped on Safari for performance) | ```tsx import { Tldraw, TextShapeUtil } from 'tldraw' import 'tldraw/tldraw.css' const ConfiguredTextUtil = TextShapeUtil.configure({ extraArrowHorizontalPadding: 20, showTextOutline: false, }) export default function App() { return (