Skip to main content
Runtimes Text

Text

Reading and modifying text at runtime.

For more information on designing and animating Text, please refer to the editor's text section:

Please ensure you're on the correct runtime version with support for Rive Text; see .

Read/Update Text Runs at Runtime

If you intend to update a text run at runtime it's important to manually enter a unique name for the run in the editor:

And then export the name: right-click and select Export name

You can identify an exported component if it's surrounded by square brackets. This makes it possible for the run to be "discoverable" at runtime by its name. For more information, see .

If the name is not set manually in the editor the name will not be part of the exported .riv (to reduce file size).

Text runs can also be updated on nested artboards at runtime, see Read / Update Nested Text Runs at Runtime below.

Examples

  • Updating Text at Runtime - Localization example

High-level API usage

Reading Text

To read a given text run text value at any given time, reference the .getTextRunValue() API on the Rive instance:

public getTextRunValue(textRunName: string): string | undefined

Supply the text run name, and you'll have the Rive text run value returned, or undefined if the text run could not be queried.

Setting Text

To set a given text run value at any given time, reference the .setTextRunValue() API on the Rive instance:

public setTextRunValue(textRunName: string, textRunValue: string): void

Supply the text run name and a second parameter, textValue, with a String value that you want to set the new text value for if the text run can be successfully queried on the active artboard.

Example Usage

import {Rive} from '@rive-app/canvas'

const r = new Rive({
  src: "my-rive-file.riv"
  artboard: "my-artboard-name",
  autoplay: true,
  stateMachines: "State Machine 1",
  onLoad: () => {
    console.log("My design-time text is, ", r.getTextRunValue("MyRun"));
    r.setTextRunValue("MyRun", "New text value");
  },
})

Low-level API usage

Get a reference to the Rive Artboard, find a text run by a given name, and get/update the text value property.

import RiveCanvas from '@rive-app/canvas-advanced';


const bytes = await (
  await fetch(new Request('./my-rive-file.riv'))
).arrayBuffer();
const myRiveFile = await rive.load(new Uint8Array(bytes));

const artboard = myRiveFile.defaultArtboard();
const textRun = artboard.textRun("MyRun"); // Query by the text run name
console.log(`My design-time text is ${textRun.text}`);
textRun.text = "Hello JS Runtime!";

...

Read/Update Nested Text Runs at Runtime

It's possible to set nested text runs at runtime—text that is not on the main artboard but on a nested artboard. See . To set a nested text run, you'll need to take note of the path where the input exists at an artboard level.

For example, to get/set the text run named button_text on the Button artboard, you need to provide the correct path.

Setting Nested Text Runs

The artboard names here are:

  • Main -> NestedArtboard -> Button

However, the path is determined based on the names set in the hierarchy:

  • ArtboardWithUniqueName -> ButtonWithUniqueName

The path is then: ArtboardWithUniqueName/ButtonWithUniqueName

Be sure to mark the nested artboards and text runs as exported.

Export nested artboard name

Do not use "/" in the name for your components, as that will break the search functionality at runtime.

Examples

  • Updating Nested Text at Runtime - Localization example

High-level API usage

Reading Text

To read a given text run text value at a specific path, reference the .getTextRunValueAtPath() API on the Rive instance:

public getTextRunValueAtPath(textRunName: string, path: string): string | undefined

Supply the text run name and the path where it is located, and you'll have the Rive text run value returned, or undefined if the text run could not be queried.

Setting Text

To set a given text run value at a specific path, reference the .setTextRunValueAtPath() API on the Rive instance:

public setTextRunValueAtPath(textRunName: string, textRunValue: string, path: string): void

Supply the textRunName, the new textValue, and the path where the run is located at a nested artboard level.

Example Usage

import {Rive} from '@rive-app/canvas'

const r = new Rive({
  src: "my-rive-file.riv"
  artboard: "my-artboard-name",
  autoplay: true,
  stateMachines: "State Machine 1",
  onLoad: () => {
    console.log("My design-time text is, ", r.getTextRunValueAtPath("MyRun", "path/to/run"));
    r.setTextRunValueAtPath("MyRun", "New text value", "path/to/run");
  },
})

Semantics for Accessibility

As Rive Text does not make use of the underlying platform text APIs, additional steps need to be taken to ensure it can be read by screen readers.

The following code snippets provide guidance on how to add semantic labels to your Rive animations. Please see the respective platform/SDKs developer documentation for additional information regarding accessibility concerns.

See Flutter's documentation on Accessibility for more information. In this example you'll use the Semantics widget to provide a label that reflects the current value of the Rive Text component.

...

String semanticLabel = '';

...

Semantics(
  label: semanticLabel,
  child: RiveAnimation.asset(
    'assets/hello_world_text.riv',
    animations: const ['Timeline 1'],
    onInit: (artboard) {
      final run = artboard.component<TextValueRun>("MyRun");
      setState(() {
        // Calling setState is needed to ensure the Semantics widget
        // rebuilds with the new value.
        semanticLabel = run?.text ?? "";
      });
    },
  ),
),
```

Or you can read the .riv file yourself and instance the artboard, see Alternative Widget Setup.

Additional Resources:

  • Accesible web animations: ARIA live regions

Fallback Fonts

When drawing text, not all glyphs (characters) may be available, such as custom fonts that may not support multiple languages, or if your embedded fonts have been set to not contain all glyphs. In these cases, it may be best to have a font that is used when a missing glyph is encountered. Some platforms have support for fallback fonts, which allow the use of system fonts as fallbacks (which should contain most missing glyphs).

On iOS and Android, sizes are ignored; instead, supplied fonts are used to render glyphs that match the styling and animation of a text run at runtime.

As of v6.1, on iOS and macOS, various options for fallbacks can be used. The Apple runtime provides helpers for selecting system fonts based on requested styling. Additionally, UIFonts / NSFonts can be used directly.

A default system font of regular weight and width will be used if no fallbacks have been registered.

// Early in your app lifecycle, call something similar to the following:
RiveFont.fallbackFonts = [
    RiveFallbackFontDescriptor(), // Use a default system font
    RiveFallbackFontDescriptor(design: .default, weight: .bold, width: .expanded), // Use a bold, expanded system font
    UIFont(name: "...", size: 20)!
]

// Alternatively, you can supply different fonts based on style at runtime

As of v6.4, on iOS and macOS, you can utilize a more dynamic callback-based API for returning various fonts depending on the style of any missing characters, as styled in a text run.

// As with the similar fallbackFonts API, you utilize Rive helper types
// or native UIFont/NSFont types

RiveFont.fallbackFontsCallback = { style in
    switch style.weight {
        case .thin: return [
            RiveFallbackFontDescriptor(weight: .thin),
            UIFont.systemFont(ofSize: 20, weight: .thin)
        ]
        case .bold: return [
            RiveFallbackFontDescriptor(weight: .bold),
            UIFont.systemFont(ofSize: 20, weight: .bold)
        ]
        default: return [
            RiveFallbackFontDescriptor(),
            UIFont.systemFont(ofSize: 20)
        ]
    }
}

// Alternatively, you can use the raw weight to return various fonts as well
RiveFont.fallbackFontsCallback = { style in
    switch style.rawWeight {
        case 100: return [
            RiveFallbackFontDescriptor(weight: .thin),
            UIFont.systemFont(ofSize: 20, weight: .thin)
        ]
        case 700: return [
            RiveFallbackFontDescriptor(weight: .bold),
            UIFont.systemFont(ofSize: 20, weight: .bold)
        ]
        default: return [
            RiveFallbackFontDescriptor(),
            UIFont.systemFont(ofSize: 20)
        ]
    }
}