Creating text

How to add text to a user's design.

Text is an essential ingredient in a designer's toolkit and apps can create text that users can then edit and manipulate with Canva's native features.

After an app adds text to a user's design, the user can manipulate the text in all the same ways they normally can using the Canva editor.

In the Developer Portal, enable the canva:design:content:write permission. In the future, the Apps SDK will throw an error if the required permissions are not enabled. To learn more, see Configuring permissions.

Import the addNativeElement method from the @canva/design package:

import { addNativeElement } from "@canva/design";
ts

Call the method, passing in the options shown here:

await addNativeElement({
type: "TEXT",
children: ["Hello world"],
});
ts

The children property accepts an array of strings, with each array item representing a separate line of text. Currently, only one item — that is, one line of text — is supported.

Apps can create line breaks in text (and therefore multiple paragraphs) by using the \n character:

await addNativeElement({
type: "TEXT",
children: [
"This is the first paragraph.\n\nThis is the second paragraph.\n\nThis is the third paragraph.",
],
});
ts

To customize the appearance of text, pass additional options into the addNativeElement method:

await addNativeElement({
type: "TEXT",
children: ["Hello world"],
// Optional
color: "#ff0099",
decoration: "underline",
fontStyle: "italic",
fontWeight: "bold",
textAlign: "center",
fontSize: 30,
top: 50,
left: 50,
width: 200,
});
ts

You can set the position of a text element using the top, left, and width properties:

  • top: The distance from the top edge of the container, in pixels.
  • left: The distance from the left edge of the container, in pixels.
  • width: The width of the element, in pixels.

If you set a fontSize value when adding a text element, you must also set the position of the text element. If you don't set the position properties, then the setting for fontSize is ignored.

Text element added to a design with a visual representation of the top, left, and width parameters

Canva has an expansive library of fonts. Apps can use a limited subset of these fonts when rendering text.

There are two ways that apps can access these fonts:

  • Open a font picker that allows the user to select a font.
  • Get a list of recommended fonts from Canva.

Generally speaking, we recommend opening the font picker.

Check out the Font design guidelines

Our design guidelines help you create a high-quality app that easily passes app review.

Apps can open a font picker that allows the user to select a font. This offers a familiar and consistent user experience, and it's the approach that we recommend for most apps.

To open the font picker:

  1. Import the requestFontSelection method from @canva/asset:

    import { requestFontSelection } from "@canva/asset";
    ts
  2. Call the method:

    const fontResponse = await requestFontSelection();
    ts

    This method opens a font picker.

    When the user selects a font, it returns a ref property for the font:

    console.log(fontResponse.font.ref);
    ts

    The ref property contains a unique identifier that references a font in Canva's backend.

  3. When creating a text element, pass the font's ref into the fontRef property:

    await addNativeElement({
    type: "TEXT",
    children: ["Hello world"],
    fontRef: fontResponse.font.ref,
    });
    ts

The requestFontSelection method doesn't automatically remember the user's previous selection. If a user selects a font, closes the font picker, and then reopens the dialog, the previously selected font won't be selected.

To fix this, an app can:

  1. Keep track of the most recently selected font — for example, with React's useState hook.
  2. For subsequent calls of the requestFontSelection method, pass the font's ref into the method.

The following example demonstrates how to do this:

import { Button, Rows, Text } from "@canva/app-ui-kit";
import { Font, requestFontSelection } from "@canva/asset";
import * as React from "react";
import styles from "styles/components.css";
export function App() {
// Keep track of the currently selected font
const [selectedFont, setSelectedFont] = React.useState<Font | undefined>();
const message = selectedFont
? `The selected font is ${selectedFont.name}.`
: `There is no font selected.`;
async function handleClick() {
const fontResponse = await requestFontSelection({
selectedFontRef: selectedFont?.ref, // Specify the selected font, if one is defined
});
if (fontResponse.type !== "COMPLETED") {
return;
}
// Update the currently selected font
setSelectedFont(fontResponse.font);
}
return (
<div className={styles.scrollContainer}>
<Rows spacing="1u">
<Text>{message}</Text>
<Button variant="primary" onClick={handleClick}>
Select a font
</Button>
</Rows>
</div>
);
}
tsx

Apps can get a list of recommended fonts from Canva. The recommendations are based on a number of factors, such as the user's locale. Apps can use this data to render a list of fonts that the user can select from.

To get a list of recommended fonts:

  1. Import the findFonts method from @canva/asset:

    import { findFonts } from "@canva/asset";
    ts
  2. Call the method:

    const fonts = await findFonts();
    ts

    This method returns an array of the recommended fonts. Each font is an object with a name, an array of weights available for that font, and a ref:

    for (const font of fonts) {
    console.log(font.name); // => "Arial"
    }
    ts
  • Apps can't set the line spacing of text.
  • Apps can't create text with a vertical writing mode.
  • Apps can't upload or define custom fonts.
  • Apps don't have access to the underlying font files.
  • The font picker doesn't list Canva Pro (paid) fonts.
  • Text can't have a predefined height.
import * as React from "react";
import { Button } from "@canva/app-ui-kit";
import styles from "styles/components.css";
export function App() {
async function handleClick() {
// Add text to the design
await addNativeElement({
// Required
type: "TEXT",
children: ["Hello world"],
// Optional
color: "#ff0099",
decoration: "underline",
fontStyle: "italic",
fontWeight: "bold",
textAlign: "center",
fontSize: 30,
top: 50,
left: 50,
width: 200,
});
}
return (
<div className={styles.scrollContainer}>
<Button variant="primary" onClick={handleClick}>
Add text to design
</Button>
</div>
);
}
tsx