On September 25th, 2024, we released v2 of the Apps SDK. To learn what’s new and how to upgrade, see Migration FAQ and Migration guide.

Recommended workflow

Canva can translate your app into other languages.

For app internationalization, Canva has defined a supported workflow that uses React and FormatJS. To help you get started, we’ve created a starter kit example that demonstrates the recommended tooling. For more information, see the Canva Apps SDK starter kit repository(opens in a new tab or window).

Prerequisites

This workflow assumes your app already has react-intl, @canva/app-i18n-kit, and @formatjs/cli installed and configured. If these dependencies aren't present in your package.json, see Migrate an existing app.

Step 1: Using FormattedMessage

Canva’s recommended i18n workflow uses the FormattedMessage component from react-intl. Ensure that your app's relevant text strings are in FormattedMessage or useIntl().formatMessage(), which allows @formatjs/cli to identify the text that needs to be extracted and translated.

  1. Import the required components from the react-intl library. For example:

    import { FormattedMessage, useIntl } from "react-intl";
    TS
  2. Use the FormattedMessage component for any text that is displayed to users. Include the following properties:

    • defaultMessage: The message to be used as the source of translations. Should be written in English (US). This is displayed to users with an English locale, or a locale for which no translations can be found.
    • description: Add a description to convey as much context as possible to a human translator. For more information, see Add notes for translators.
    • values: (Optional) Any dynamic values that need to be included in the string.

    For example:

    import { FormattedMessage, useIntl } from "react-intl";
    // ...
    <Text>
    <FormattedMessage
    description="Message that welcomes the user to the app"
    defaultMessage="Welcome to {appName}."
    values={{ appName: 'My Cool App' }}
    />
    </Text>
    TS

    Avoid hardcoding English language for aria-labels and other assistive text. Instead, you can useintl.formatMessage. For example:

    const intl = useIntl();
    // ...
    <Button
    variant="primary"
    icon={RotateIcon}
    ariaLabel={intl.formatMessage({
    defaultMessage: "Rotate the image",
    description:
    "Label text for a button. Explains that the image will rotate when pressed",
    })}
    />
    TS

Step 2: Testing localization

The @canva/app-i18n-kit package lets you test your app using pseudolocalization, and lets you change the locale using the Developer menu. This gives you a preview of what your app could look like in a different locale.

The text lets you read your original English text, but inserts non-ASCII characters and adds width to each string to simulate lengthier languages.

This approach is only compatible with our recommended tooling.

  1. Enable pseudolocalization in the Developer menu. This shows you a preview of how different characters and text lengths affect the UI.

    Developer menu with the pseudolocalize option selected

    • Check that any custom components respect the left-to-right and right-to-left setting.
    • Make sure there are no rendering issues or truncated text.

You can’t preview or test actual translations, since these are only available after your app has been approved. However, you can then preview the translations before releasing your app.

Step 3: Generate the JSON file

This process extracts all the FormattedMessage and useIntl().formatMessage() strings in your code and saves them to a JSON file. You can then upload this file to Canva for translation.

The JSON file is subject to these limitations:

  • The description and defaultMessage keys must be present.
  • Don't add additional keys.
  • The description and defaultMessage values must not be empty or missing.
  • The description and defaultMessage values must be text strings and must not exceed 500 characters.
  • The number of messages must not exceed 100.
  • Messages must not use unsupported ICU syntax. For more information, see ICU syntax.

The recommended tooling automatically generates files in the required format. To generate the messages_en.json file, run the following command:

npm run build
SHELL

This example shows what a typical message can look like:

{
"1eigR4": {
"defaultMessage": "Rotate the image",
"description": "Label text for a button. Explains that the image will rotate when pressed."
}
}
JSON

Step 4: Upload the JSON file

As part of the app submission process, you can upload the JSON file for translation.

  1. Locate your app in the Developer Portal.
  2. Upload the messages_en.json file, using the Translations file input.

Next steps

Canva reviews your app and identifies which locales should be supported. Canva then performs the translation of the supplied strings. You’ll be automatically notified once Canva has finished the translation process. You can then preview your app in the supported locales.

More information