selection.registerOnChange

API reference for the selection.registerOnChange method.

Registers a callback that runs when the specified type of content is selected.

This callback fires immediately if content is already selected when the callback is registered.

Usage

Handling plaintext selection

import { selection } from "@canva/design";
selection.registerOnChange({
scope: 'plaintext',
onChange: async (event) => {
if (event.count > 0) {
const draft = await event.read();
// Do something with the selected text, e.g. `draft.contents[0].text`
}
}
});
TYPESCRIPT

Handling image selection

import { selection } from "@canva/design";
selection.registerOnChange({
scope: 'image',
onChange: async (event) => {
if (event.count > 0) {
const draft = await event.read();
// Do something with the selected image ref, e.g. `draft.contents[0].ref`
}
}
});
TYPESCRIPT

Handling video selection

import { selection } from "@canva/design";
selection.registerOnChange({
scope: 'video',
onChange: async (event) => {
if (event.count > 0) {
const draft = await event.read();
// Do something with the selected video ref, e.g. `draft.contents[0].ref`
}
}
});
TYPESCRIPT

Handling richtext selection

import { selection } from "@canva/design";
selection.registerOnChange({
scope: 'richtext',
onChange: async (event) => {
if (event.count > 0) {
const draft = await event.read();
const range = draft.contents[0];
// Do something with the selected richtext, e.g. `range.readPlaintext()`
}
}
});
TYPESCRIPT

Parameters

optsobject
Required

Options for configuring the content selection callback.

scopeScope
Required

The type of content that triggers a selection change event.

Available values:

  • "plaintext"
  • "image"
  • "video"
  • "richtext"
onChangefunction
Required

The callback to run when the selected content changes.

Parameters

eventSelectionEvent<Scope>
Required

Information about the selection change event.

scopeScopeRead-only
Required

The type of content that's selected.

Available values:

  • "plaintext"
  • "image"
  • "video"
  • "richtext"
countnumberRead-only
Required

The number of selected elements.

readfunction
Required

Returns a snapshot of the content in the user's selection.

The snapshot is known as the draft.

Returns

A snapshot of content from a user's design. This is a Promise that resolves with the following object:

contentsSelectionValue<Scope>[]Read-only

The individual content items that exist within the snapshot.

Any changes made to this array won't be reflected in the user's design until the save method is called.

textstring

The text content.

refImageRef

A unique identifier that points to an image asset in Canva's backend.

refVideoRef

A unique identifier that points to an video asset in Canva's backend.

Provides methods for interacting with a range of formatted text.

formatParagraphfunction

Formats all of the paragraphs that overlap the given bounds.

  • The \n character indicates the end of a paragraph.
  • All paragraphs that overlap the provided bounds will be formatted in their entirety.

Parameters

boundsBounds
Required

The segment of the range on which to apply the formatting.

indexnumber
Required

The starting position of the segment.

This is zero-based, meaning the first character of the range is at index 0.

lengthnumber
Required

The number of characters in the segment, starting from the index.

formattingRichtextFormatting
Required

The formatting to apply to the paragraph(s).

colorstring
Optional

The color of the text as a hex code.

The hex code must include all six characters and be prefixed with a # symbol.

Example

"#ff0099"
TS
fontWeightFontWeight
Optional

The weight (thickness) of the font.

The available font weights depend on the font.

Default value: "normal"

Available values:

  • "normal"
  • "thin"
  • "extralight"
  • "light"
  • "medium"
  • "semibold"
  • "bold"
  • "ultrabold"
  • "heavy"
fontStylestring
Optional

The style of the font.

Default value: "normal"

Available values:

  • "normal"
  • "italic"
decorationstring
Optional

The decoration of the text.

Default value: "none"

Available values:

  • "none"
  • "underline"
strikethroughstring
Optional

The strikethrough of the text.

Default value: "none"

Available values:

  • "none"
  • "strikethrough"
fontRefFontRef
Optional

A unique identifier that points to a font asset in Canva's backend.

fontSizenumber
Optional

The size of the text, in pixels.

  • In the Canva editor, this number is shown as points (pts), not pixels.

Minimum: 1

Maximum: 100

textAlignstring
Optional

The alignment of the text.

Default value: "start"

Available values:

  • "start"
  • "center"
  • "end"
  • "justify"
listLevelnumber
Optional

The list indentation level of the paragraph.

listMarkerstring
Optional

The appearance of list item markers.

This property only has an effect if listLevel is greater than 0.

Default value: "none"

Available values:

  • "none"
  • "disc"
  • "circle"
  • "square"
  • "decimal"
  • "lower-alpha"
  • "lower-roman"
  • "checked"
  • "unchecked"

Returns

void

Examples

Format paragraph as a heading

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
range.appendText("Heading Text\nRegular paragraph text.");
// Format just the first paragraph as a heading
range.formatParagraph(
{ index: 0, length: 12 }, // Only need to include part of the paragraph
{
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center'
}
);
TYPESCRIPT

Create a bulleted list

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
const text = "Item 1\nItem 2\nItem 3";
range.appendText(text);
// Format all paragraphs as a bulleted list
range.formatParagraph(
{ index: 0, length: text.length },
{
listLevel: 1,
listMarker: 'disc'
}
);
TYPESCRIPT
formatTextfunction

Formats a region of text with inline formatting properties.

Parameters

boundsBounds
Required

The segment of the range on which to apply the formatting.

indexnumber
Required

The starting position of the segment.

This is zero-based, meaning the first character of the range is at index 0.

lengthnumber
Required

The number of characters in the segment, starting from the index.

formattingInlineFormatting
Required

The formatting to apply to the text.

colorstring
Optional

The color of the text as a hex code.

The hex code must include all six characters and be prefixed with a # symbol.

Example

"#ff0099"
TS
fontWeightFontWeight
Optional

The weight (thickness) of the font.

The available font weights depend on the font.

Default value: "normal"

Available values:

  • "normal"
  • "thin"
  • "extralight"
  • "light"
  • "medium"
  • "semibold"
  • "bold"
  • "ultrabold"
  • "heavy"
fontStylestring
Optional

The style of the font.

Default value: "normal"

Available values:

  • "normal"
  • "italic"
decorationstring
Optional

The decoration of the text.

Default value: "none"

Available values:

  • "none"
  • "underline"
strikethroughstring
Optional

The strikethrough of the text.

Default value: "none"

Available values:

  • "none"
  • "strikethrough"

Returns

void

Examples

Format specific words in a paragraph

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
range.appendText("This text contains important information.");
// Format just the word "important"
range.formatText(
{ index: 16, length: 9 },
{
fontWeight: 'bold',
color: '#FF0000'
}
);
TYPESCRIPT

Add a link to text

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
range.appendText("Visit our website for more information.");
// Add a link to "our website"
range.formatText(
{ index: 6, length: 11 },
{
link: "https://www.example.com",
decoration: 'underline',
color: '#0066CC'
}
);
TYPESCRIPT
appendTextfunction

Appends the specified characters to the end of the range.

Parameters

charactersstring
Required

The characters to append to the richtext range.

formattingInlineFormatting
Optional

Optional formatting to apply to the appended text.

colorstring
Optional

The color of the text as a hex code.

The hex code must include all six characters and be prefixed with a # symbol.

Example

"#ff0099"
TS
fontWeightFontWeight
Optional

The weight (thickness) of the font.

The available font weights depend on the font.

Default value: "normal"

Available values:

  • "normal"
  • "thin"
  • "extralight"
  • "light"
  • "medium"
  • "semibold"
  • "bold"
  • "ultrabold"
  • "heavy"
fontStylestring
Optional

The style of the font.

Default value: "normal"

Available values:

  • "normal"
  • "italic"
decorationstring
Optional

The decoration of the text.

Default value: "none"

Available values:

  • "none"
  • "underline"
strikethroughstring
Optional

The strikethrough of the text.

Default value: "none"

Available values:

  • "none"
  • "strikethrough"

Returns

boundsBounds

A segment of a richtext range.

indexnumber

The starting position of the segment.

This is zero-based, meaning the first character of the range is at index 0.

lengthnumber

The number of characters in the segment, starting from the index.

Examples

Append plain text

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
range.appendText("First paragraph. ");
// Append more text to the existing content
const result = range.appendText("This is additional text.");
// The bounds of the newly added text are returned
// Do something with the bounds - result.bounds, e.g. { index: 17, length: 24 }
TYPESCRIPT

Append formatted text

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
range.appendText("Normal text followed by ");
// Append formatted text
range.appendText("bold red text", {
fontWeight: 'bold',
color: '#FF0000'
});
// Append a new paragraph
range.appendText("\nThis is a new paragraph.");
TYPESCRIPT
replaceTextfunction

Replaces a region of text with the specified characters.

Parameters

boundsBounds
Required

The segment of the range to replace.

indexnumber
Required

The starting position of the segment.

This is zero-based, meaning the first character of the range is at index 0.

lengthnumber
Required

The number of characters in the segment, starting from the index.

charactersstring
Required

The replacement characters.

formattingInlineFormatting
Optional

The formatting to apply to the replaced text.

colorstring
Optional

The color of the text as a hex code.

The hex code must include all six characters and be prefixed with a # symbol.

Example

"#ff0099"
TS
fontWeightFontWeight
Optional

The weight (thickness) of the font.

The available font weights depend on the font.

Default value: "normal"

Available values:

  • "normal"
  • "thin"
  • "extralight"
  • "light"
  • "medium"
  • "semibold"
  • "bold"
  • "ultrabold"
  • "heavy"
fontStylestring
Optional

The style of the font.

Default value: "normal"

Available values:

  • "normal"
  • "italic"
decorationstring
Optional

The decoration of the text.

Default value: "none"

Available values:

  • "none"
  • "underline"
strikethroughstring
Optional

The strikethrough of the text.

Default value: "none"

Available values:

  • "none"
  • "strikethrough"

Returns

boundsBounds

The bounds of the replacement characters within the updated range.

indexnumber

The starting position of the segment.

This is zero-based, meaning the first character of the range is at index 0.

lengthnumber

The number of characters in the segment, starting from the index.

Examples

Replace text while maintaining some formatting

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
range.appendText("This text needs correction.");
// Replace "needs correction" with "is correct"
const result = range.replaceText(
{ index: 10, length: 16 },
"is correct"
);
// The bounds of the replaced text are returned
// Do something with the bounds - result.bounds, e.g. { index: 10, length: 10 }
TYPESCRIPT

Replace text with formatted text

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
range.appendText("Regular text that needs emphasis.");
// Replace "needs emphasis" with formatted text
range.replaceText(
{ index: 17, length: 15 },
"is important",
{
fontWeight: 'bold',
fontStyle: 'italic',
color: '#0066CC'
}
);
TYPESCRIPT
readPlaintextfunction

Returns the current state of the richtext as plaintext.

Returns

string

Examples

Extract plain text content

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
range.appendText("First paragraph.\n", { fontWeight: 'bold' });
range.appendText("Second paragraph with formatting.", { color: '#FF0000' });
// Get plain text content without formatting
const plainText = range.readPlaintext();
// Do something with the plain text - plainText, e.g. "First paragraph.\nSecond paragraph with formatting."
TYPESCRIPT

Search within text content

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
range.appendText("This text contains a searchable term.");
// Search for a specific word
const plainText = range.readPlaintext();
const searchTerm = "searchable";
const index = plainText.indexOf(searchTerm);
if (index !== -1) {
// Format the found term
range.formatText(
{ index, length: searchTerm.length },
{ fontWeight: 'bold', decoration: 'underline' }
);
}
TYPESCRIPT
readTextRegionsfunction

Returns the current state of the richtext as one or more text regions. Each region is an object that contains the text content and its formatting.

Returns

textstring

The plaintext content of the region.

formattingPartial<RichtextFormatting>
Optional

The formatting of the region.

colorstring
Optional

The color of the text as a hex code.

The hex code must include all six characters and be prefixed with a # symbol.

Example

"#ff0099"
TS
fontWeightFontWeight
Optional

The weight (thickness) of the font.

The available font weights depend on the font.

Default value: "normal"

Available values:

  • "normal"
  • "thin"
  • "extralight"
  • "light"
  • "medium"
  • "semibold"
  • "bold"
  • "ultrabold"
  • "heavy"
fontStylestring
Optional

The style of the font.

Default value: "normal"

Available values:

  • "normal"
  • "italic"
decorationstring
Optional

The decoration of the text.

Default value: "none"

Available values:

  • "none"
  • "underline"
strikethroughstring
Optional

The strikethrough of the text.

Default value: "none"

Available values:

  • "none"
  • "strikethrough"
fontRefFontRef
Optional

A unique identifier that points to a font asset in Canva's backend.

fontSizenumber
Optional

The size of the text, in pixels.

  • In the Canva editor, this number is shown as points (pts), not pixels.

Minimum: 1

Maximum: 100

textAlignstring
Optional

The alignment of the text.

Default value: "start"

Available values:

  • "start"
  • "center"
  • "end"
  • "justify"
listLevelnumber
Optional

The list indentation level of the paragraph.

listMarkerstring
Optional

The appearance of list item markers.

This property only has an effect if listLevel is greater than 0.

Default value: "none"

Available values:

  • "none"
  • "disc"
  • "circle"
  • "square"
  • "decimal"
  • "lower-alpha"
  • "lower-roman"
  • "checked"
  • "unchecked"

Examples

Get text with formatting information

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
range.appendText("Normal text ", {});
range.appendText("bold text", { fontWeight: 'bold' });
range.appendText(" and ", {});
range.appendText("red text", { color: '#FF0000' });
// Get formatted regions
const regions = range.readTextRegions();
// Do something with the regions, e.g.
// [
// { text: "Normal text ", formatting: {} },
// { text: "bold text", formatting: { fontWeight: 'bold' } },
// { text: " and ", formatting: {} },
// { text: "red text", formatting: { color: '#FF0000' } }
// ]
TYPESCRIPT

Analyze formatting variations

import { createRichtextRange } from "@canva/design";
const range = createRichtextRange();
range.appendText("Mixed ", {});
range.appendText("formatted ", { fontWeight: 'bold' });
range.appendText("text", { color: '#0066CC' });
// Analyze formatting variations
const regions = range.readTextRegions();
const formattingTypes = regions.map(region => {
const formatting = region.formatting || {};
return {
text: region.text,
hasWeight: !!formatting.fontWeight,
hasColor: !!formatting.color
};
});
TYPESCRIPT
savefunction

Saves changes made to the content items in the contents array.

Once this method is called:

  • Any changes the app has made to to the content will be reflected in the user's design.
  • Any changes the user has made to the content since the snapshot was created may be overwritten.
  • Only properties that are different from the original state will be written to the design.

Returns

Promise<void>

Examples

Save changes to selected text

import { selection } from "@canva/design";
selection.registerOnChange({
scope: 'plaintext',
onChange: async (event) => {
if (event.count > 0) {
const draft = await event.read();
// Make changes to the content
for (const content of draft.contents) {
content.text = content.text.toUpperCase();
}
// Save the changes to the design
await draft.save();
}
}
});
TYPESCRIPT

Modify then save rich text content

import { selection } from "@canva/design";
selection.registerOnChange({
scope: 'richtext',
onChange: async (event) => {
if (event.count > 0) {
const draft = await event.read();
const range = draft.contents[0];
// Get the plain text
const text = range.readPlaintext();
// Apply formatting to the entire text
range.formatText(
{ index: 0, length: text.length },
{ fontWeight: 'bold', color: '#0066CC' }
);
// Save the formatted text back to the design
await draft.save();
}
}
});
TYPESCRIPT

Returns

void

Returns

() => void