> ## Documentation Index
> Fetch the complete documentation index at: https://www.canva.dev/docs/apps/llms.txt
> Use this file to discover all available pages before exploring further.
# editContent
API reference for the editContent method.
NOTE: **This API is a preview**. Preview APIs are unstable and may change without warning. You can't release public apps using this API until it's stable.
Reads and edits richtext content from the user's design.
## Parameters
Options for configuring how a design is read. Must specify `contentType: 'richtext'`.
Properties of options>}>
The only valid value is `"current_page"`.
The only valid value is `"richtext"`.
A callback that receives a `RichtextContentSession` for editing.
**Parameters**
A callback for reading and updating the requested design content.
**Param: session**
The result of reading the content in the design.
**Examples**
**Read and update richtext content**
```typescript
import { editContent } from "@canva/design";
await editContent(
{ contentType: 'richtext', target: 'current_page' },
async (session) => {
// Read the content
const contents = session.contents;
if (contents.length > 0) {
const range = contents[0];
// Modify the content (e.g., adding text)
range.appendText("\nAppended text from app");
// Sync changes back to the design
await session.sync();
}
}
);
```
**Format all richtext content in the design**
```typescript
import { editContent } from "@canva/design";
await editContent(
{ contentType: 'richtext', target: 'current_page' },
async (session) => {
// Process each richtext range in the content
for (const range of session.contents) {
// Skip if the content has been deleted
if (range.deleted) continue;
// Get the text content
const text = range.readPlaintext();
if (text.length === 0) continue;
// Apply consistent formatting
range.formatParagraph(
{ index: 0, length: text.length },
{
fontRef: 'YOUR_FONT_REF',
fontSize: 16,
textAlign: 'start'
}
);
}
// Sync all changes back to the design
await session.sync();
}
);
```
**Modify content without saving changes**
```typescript
import { editContent } from "@canva/design";
await editContent(
{ contentType: 'richtext', target: 'current_page' },
async (session) => {
// Read and analyze the content without making changes
for (const range of session.contents) {
const text = range.readPlaintext();
// Do something with the content preview, e.g. `text.substring(0, 50)`
// No call to session.sync() means no changes are saved
}
// Since we're not calling sync(), no changes will be made to the design
}
);
```
Properties of session>}>
Richtext content in the design.
Properties of contents>}>
Indicates whether the object containing this richtext range has been deleted.
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**
The segment of the range on which to apply the formatting.
Properties of bounds>}>
The starting position of the segment.
This is zero-based, meaning the first character of the range is at index 0.
The number of characters in the segment, starting from the index.
The formatting to apply to the paragraph(s).
Properties of formatting>}>
The color of the text as a hex code.
The hex code must include all six characters and be prefixed with a `#` symbol.
**Example**
```ts
"#ff0099"
```
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"`
The style of the font.
**Default value**: `"normal"`
**Available values**:
* `"normal"`
* `"italic"`
The decoration of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"underline"`
The strikethrough of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"strikethrough"`
An external URL that the text links to.
A unique identifier that points to a font asset in Canva's backend.
The size of the text, in pixels.
* In the Canva editor, this number is shown as points (pts), not pixels.
**Minimum**: `1`
**Maximum**: `1000`
The alignment of the text.
**Default value**: `"start"`
**Available values**:
* `"start"`
* `"center"`
* `"end"`
* `"justify"`
The list indentation level of the paragraph.
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"`
The line height of the paragraph, relative to the font size expressed in Em.
**Minimum**: `0.5`
**Maximum**: `2.5`
**Default value**: `1.4`
The spacing between characters, relative to the font size expressed in Em.
* In the Canva editor, this number is shown as a multiple of 1000.
**Minimum**: `-0.2`
**Maximum**: `0.8`
**Default value**: `0`
**Returns**
`void`
**Examples**
**Format paragraph as a heading**
```typescript
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'
}
);
```
**Create a bulleted list**
```typescript
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'
}
);
```
Formats a region of text with inline formatting properties.
**Parameters**
The segment of the range on which to apply the formatting.
Properties of bounds>}>
The starting position of the segment.
This is zero-based, meaning the first character of the range is at index 0.
The number of characters in the segment, starting from the index.
The formatting to apply to the text.
Properties of formatting>}>
The color of the text as a hex code.
The hex code must include all six characters and be prefixed with a `#` symbol.
**Example**
```ts
"#ff0099"
```
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"`
The style of the font.
**Default value**: `"normal"`
**Available values**:
* `"normal"`
* `"italic"`
The decoration of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"underline"`
The strikethrough of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"strikethrough"`
An external URL that the text links to.
**Returns**
`void`
**Examples**
**Format specific words in a paragraph**
```typescript
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'
}
);
```
**Add a link to text**
```typescript
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'
}
);
```
Appends the specified characters to the end of the range.
**Parameters**
The characters to append to the richtext range.
Optional formatting to apply to the appended text.
Properties of formatting>}>
The color of the text as a hex code.
The hex code must include all six characters and be prefixed with a `#` symbol.
**Example**
```ts
"#ff0099"
```
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"`
The style of the font.
**Default value**: `"normal"`
**Available values**:
* `"normal"`
* `"italic"`
The decoration of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"underline"`
The strikethrough of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"strikethrough"`
An external URL that the text links to.
**Returns**
A segment of a richtext range.
Properties of bounds>}>
The starting position of the segment.
This is zero-based, meaning the first character of the range is at index 0.
The number of characters in the segment, starting from the index.
**Examples**
**Append plain text**
```typescript
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 }
```
**Append formatted text**
```typescript
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.");
```
Replaces a region of text with the specified characters.
**Parameters**
The segment of the range to replace.
Properties of bounds>}>
The starting position of the segment.
This is zero-based, meaning the first character of the range is at index 0.
The number of characters in the segment, starting from the index.
The replacement characters.
The formatting to apply to the replaced text.
Properties of formatting>}>
The color of the text as a hex code.
The hex code must include all six characters and be prefixed with a `#` symbol.
**Example**
```ts
"#ff0099"
```
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"`
The style of the font.
**Default value**: `"normal"`
**Available values**:
* `"normal"`
* `"italic"`
The decoration of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"underline"`
The strikethrough of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"strikethrough"`
An external URL that the text links to.
**Returns**
The bounds of the replacement characters within the updated range.
Properties of bounds>}>
The starting position of the segment.
This is zero-based, meaning the first character of the range is at index 0.
The number of characters in the segment, starting from the index.
**Examples**
**Replace text while maintaining some formatting**
```typescript
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 }
```
**Replace text with formatted text**
```typescript
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'
}
);
```
Returns the current state of the richtext as plaintext.
**Returns**
`string`
**Examples**
**Extract plain text content**
```typescript
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."
```
**Search within text content**
```typescript
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' }
);
}
```
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**
The plaintext content of the region.
The formatting of the region.
Properties of formatting>}>
The color of the text as a hex code.
The hex code must include all six characters and be prefixed with a `#` symbol.
**Example**
```ts
"#ff0099"
```
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"`
The style of the font.
**Default value**: `"normal"`
**Available values**:
* `"normal"`
* `"italic"`
The decoration of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"underline"`
The strikethrough of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"strikethrough"`
An external URL that the text links to.
A unique identifier that points to a font asset in Canva's backend.
The size of the text, in pixels.
* In the Canva editor, this number is shown as points (pts), not pixels.
**Minimum**: `1`
**Maximum**: `1000`
The alignment of the text.
**Default value**: `"start"`
**Available values**:
* `"start"`
* `"center"`
* `"end"`
* `"justify"`
The list indentation level of the paragraph.
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"`
The line height of the paragraph, relative to the font size expressed in Em.
**Minimum**: `0.5`
**Maximum**: `2.5`
**Default value**: `1.4`
The spacing between characters, relative to the font size expressed in Em.
* In the Canva editor, this number is shown as a multiple of 1000.
**Minimum**: `-0.2`
**Maximum**: `0.8`
**Default value**: `0`
**Examples**
**Get text with formatting information**
```typescript
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' } }
// ]
```
**Analyze formatting variations**
```typescript
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
};
});
```
Saves any changes made during the session while keeping the transaction open.
* Any changes in the session are only reflected in the design after this method is called.
* Once this method is called, further changes in the session can still be made.
**Returns**
`Promise`
**Example: Sync changes after modifying content**
```typescript
import { editContent } from "@canva/design";
await editContent(
{ contentType: 'richtext', target: 'current_page' },
async (session) => {
if (session.contents.length > 0) {
const range = session.contents[0];
// Make modifications to the content
range.appendText(" - Modified by app");
try {
// Save changes back to the design
await session.sync();
} catch (error) {
console.error('Failed to sync changes:', error);
}
}
}
);
```
**Returns**
`void` or `Promise`
## Returns
A promise that resolves when editing is complete.
`Promise`
Reads and edits fill content from the user's design.
## Parameters
Options for configuring how a design is read. Must specify `contentType: 'fill'`.
Properties of options>}>
The only valid value is `"current_page"`.
The only valid value is `"fill"`.
A callback that receives a `FillContentSession` for editing.
**Parameters**
Session for reading and updating fill content in a user's design.
Properties of session>}>
Fill content in the design.
The only valid value is `"image"`.
A unique identifier that points to an image asset in Canva's backend.
Indicates whether the object containing this fill has been deleted.
A description of the image content.
Use `undefined` for content with no description.
Properties of altText>}>
The text content.
Indicates where the alternative text should be displayed.
* If `true`, the alternative text will only be displayed in the editor.
* If `false`, the alternative text will be displayed in the editor and in view-only mode.
The only valid value is `"video"`.
A unique identifier that points to an video asset in Canva's backend.
Indicates whether the object containing this fill has been deleted.
A description of the video content.
Use `undefined` for content with no description.
Properties of altText>}>
The text content.
Indicates where the alternative text should be displayed.
* If `true`, the alternative text will only be displayed in the editor.
* If `false`, the alternative text will be displayed in the editor and in view-only mode.
* Any changes in the session are only reflected in the design after this method is called.
* Once this method is called, further changes in the session can still be made.
**Returns**
`Promise`
**Returns**
`void` or `Promise`
## Returns
A promise that resolves when editing is complete.
`Promise`
Reads and edits content from the user's design.
## Parameters
Options for configuring how a design is read. Must specify a content type.
Properties of options>}>
The only valid value is `"current_page"`.
**Available values**:
* `"richtext"`
* `"fill"`
A callback that receives a session for editing.
**Parameters**
A callback for reading and updating the requested design content.
**Param: session**
The result of reading the content in the design.
**Examples**
**Read and update richtext content**
```typescript
import { editContent } from "@canva/design";
await editContent(
{ contentType: 'richtext', target: 'current_page' },
async (session) => {
// Read the content
const contents = session.contents;
if (contents.length > 0) {
const range = contents[0];
// Modify the content (e.g., adding text)
range.appendText("\nAppended text from app");
// Sync changes back to the design
await session.sync();
}
}
);
```
**Format all richtext content in the design**
```typescript
import { editContent } from "@canva/design";
await editContent(
{ contentType: 'richtext', target: 'current_page' },
async (session) => {
// Process each richtext range in the content
for (const range of session.contents) {
// Skip if the content has been deleted
if (range.deleted) continue;
// Get the text content
const text = range.readPlaintext();
if (text.length === 0) continue;
// Apply consistent formatting
range.formatParagraph(
{ index: 0, length: text.length },
{
fontRef: 'YOUR_FONT_REF',
fontSize: 16,
textAlign: 'start'
}
);
}
// Sync all changes back to the design
await session.sync();
}
);
```
**Modify content without saving changes**
```typescript
import { editContent } from "@canva/design";
await editContent(
{ contentType: 'richtext', target: 'current_page' },
async (session) => {
// Read and analyze the content without making changes
for (const range of session.contents) {
const text = range.readPlaintext();
// Do something with the content preview, e.g. `text.substring(0, 50)`
// No call to session.sync() means no changes are saved
}
// Since we're not calling sync(), no changes will be made to the design
}
);
```
Richtext content in the design.
Properties of contents>}>
Indicates whether the object containing this richtext range has been deleted.
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**
The segment of the range on which to apply the formatting.
Properties of bounds>}>
The starting position of the segment.
This is zero-based, meaning the first character of the range is at index 0.
The number of characters in the segment, starting from the index.
The formatting to apply to the paragraph(s).
Properties of formatting>}>
The color of the text as a hex code.
The hex code must include all six characters and be prefixed with a `#` symbol.
**Example**
```ts
"#ff0099"
```
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"`
The style of the font.
**Default value**: `"normal"`
**Available values**:
* `"normal"`
* `"italic"`
The decoration of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"underline"`
The strikethrough of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"strikethrough"`
An external URL that the text links to.
A unique identifier that points to a font asset in Canva's backend.
The size of the text, in pixels.
* In the Canva editor, this number is shown as points (pts), not pixels.
**Minimum**: `1`
**Maximum**: `1000`
The alignment of the text.
**Default value**: `"start"`
**Available values**:
* `"start"`
* `"center"`
* `"end"`
* `"justify"`
The list indentation level of the paragraph.
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"`
The line height of the paragraph, relative to the font size expressed in Em.
**Minimum**: `0.5`
**Maximum**: `2.5`
**Default value**: `1.4`
The spacing between characters, relative to the font size expressed in Em.
* In the Canva editor, this number is shown as a multiple of 1000.
**Minimum**: `-0.2`
**Maximum**: `0.8`
**Default value**: `0`
**Returns**
`void`
**Examples**
**Format paragraph as a heading**
```typescript
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'
}
);
```
**Create a bulleted list**
```typescript
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'
}
);
```
Formats a region of text with inline formatting properties.
**Parameters**
The segment of the range on which to apply the formatting.
Properties of bounds>}>
The starting position of the segment.
This is zero-based, meaning the first character of the range is at index 0.
The number of characters in the segment, starting from the index.
The formatting to apply to the text.
Properties of formatting>}>
The color of the text as a hex code.
The hex code must include all six characters and be prefixed with a `#` symbol.
**Example**
```ts
"#ff0099"
```
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"`
The style of the font.
**Default value**: `"normal"`
**Available values**:
* `"normal"`
* `"italic"`
The decoration of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"underline"`
The strikethrough of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"strikethrough"`
An external URL that the text links to.
**Returns**
`void`
**Examples**
**Format specific words in a paragraph**
```typescript
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'
}
);
```
**Add a link to text**
```typescript
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'
}
);
```
Appends the specified characters to the end of the range.
**Parameters**
The characters to append to the richtext range.
Optional formatting to apply to the appended text.
Properties of formatting>}>
The color of the text as a hex code.
The hex code must include all six characters and be prefixed with a `#` symbol.
**Example**
```ts
"#ff0099"
```
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"`
The style of the font.
**Default value**: `"normal"`
**Available values**:
* `"normal"`
* `"italic"`
The decoration of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"underline"`
The strikethrough of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"strikethrough"`
An external URL that the text links to.
**Returns**
A segment of a richtext range.
Properties of bounds>}>
The starting position of the segment.
This is zero-based, meaning the first character of the range is at index 0.
The number of characters in the segment, starting from the index.
**Examples**
**Append plain text**
```typescript
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 }
```
**Append formatted text**
```typescript
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.");
```
Replaces a region of text with the specified characters.
**Parameters**
The segment of the range to replace.
Properties of bounds>}>
The starting position of the segment.
This is zero-based, meaning the first character of the range is at index 0.
The number of characters in the segment, starting from the index.
The replacement characters.
The formatting to apply to the replaced text.
Properties of formatting>}>
The color of the text as a hex code.
The hex code must include all six characters and be prefixed with a `#` symbol.
**Example**
```ts
"#ff0099"
```
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"`
The style of the font.
**Default value**: `"normal"`
**Available values**:
* `"normal"`
* `"italic"`
The decoration of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"underline"`
The strikethrough of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"strikethrough"`
An external URL that the text links to.
**Returns**
The bounds of the replacement characters within the updated range.
Properties of bounds>}>
The starting position of the segment.
This is zero-based, meaning the first character of the range is at index 0.
The number of characters in the segment, starting from the index.
**Examples**
**Replace text while maintaining some formatting**
```typescript
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 }
```
**Replace text with formatted text**
```typescript
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'
}
);
```
Returns the current state of the richtext as plaintext.
**Returns**
`string`
**Examples**
**Extract plain text content**
```typescript
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."
```
**Search within text content**
```typescript
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' }
);
}
```
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**
The plaintext content of the region.
The formatting of the region.
Properties of formatting>}>
The color of the text as a hex code.
The hex code must include all six characters and be prefixed with a `#` symbol.
**Example**
```ts
"#ff0099"
```
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"`
The style of the font.
**Default value**: `"normal"`
**Available values**:
* `"normal"`
* `"italic"`
The decoration of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"underline"`
The strikethrough of the text.
**Default value**: `"none"`
**Available values**:
* `"none"`
* `"strikethrough"`
An external URL that the text links to.
A unique identifier that points to a font asset in Canva's backend.
The size of the text, in pixels.
* In the Canva editor, this number is shown as points (pts), not pixels.
**Minimum**: `1`
**Maximum**: `1000`
The alignment of the text.
**Default value**: `"start"`
**Available values**:
* `"start"`
* `"center"`
* `"end"`
* `"justify"`
The list indentation level of the paragraph.
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"`
The line height of the paragraph, relative to the font size expressed in Em.
**Minimum**: `0.5`
**Maximum**: `2.5`
**Default value**: `1.4`
The spacing between characters, relative to the font size expressed in Em.
* In the Canva editor, this number is shown as a multiple of 1000.
**Minimum**: `-0.2`
**Maximum**: `0.8`
**Default value**: `0`
**Examples**
**Get text with formatting information**
```typescript
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' } }
// ]
```
**Analyze formatting variations**
```typescript
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
};
});
```
Saves any changes made during the session while keeping the transaction open.
* Any changes in the session are only reflected in the design after this method is called.
* Once this method is called, further changes in the session can still be made.
**Returns**
`Promise`
**Example: Sync changes after modifying content**
```typescript
import { editContent } from "@canva/design";
await editContent(
{ contentType: 'richtext', target: 'current_page' },
async (session) => {
if (session.contents.length > 0) {
const range = session.contents[0];
// Make modifications to the content
range.appendText(" - Modified by app");
try {
// Save changes back to the design
await session.sync();
} catch (error) {
console.error('Failed to sync changes:', error);
}
}
}
);
```
}>
Session for reading and updating fill content in a user's design.
Fill content in the design.
The only valid value is `"image"`.
A unique identifier that points to an image asset in Canva's backend.
Indicates whether the object containing this fill has been deleted.
A description of the image content.
Use `undefined` for content with no description.
Properties of altText>}>
The text content.
Indicates where the alternative text should be displayed.
* If `true`, the alternative text will only be displayed in the editor.
* If `false`, the alternative text will be displayed in the editor and in view-only mode.
The only valid value is `"video"`.
A unique identifier that points to an video asset in Canva's backend.
Indicates whether the object containing this fill has been deleted.
A description of the video content.
Use `undefined` for content with no description.
Properties of altText>}>
The text content.
Indicates where the alternative text should be displayed.
* If `true`, the alternative text will only be displayed in the editor.
* If `false`, the alternative text will be displayed in the editor and in view-only mode.
* Any changes in the session are only reflected in the design after this method is called.
* Once this method is called, further changes in the session can still be made.
**Returns**
`Promise`
**Returns**
`void` or `Promise`
## Returns
A promise that resolves when editing is complete.
`Promise`
## Permissions
To use this method, the following permissions must be enabled for the app:
* `canva:design:content:read`, to read the content
* `canva:design:content:write`, if the app calls the `sync` method
To learn more, see [Permissions](https://www.canva.dev/docs/apps/configuring-intents-permissions/).
## Rate limit
This method has the following rate limits:
* Reading content: 10 requests every 10 seconds
* Calling the `sync` method: 10 requests every 10 seconds