Skip to main content
Semantics is currently only available in Early Access. Runtime support is in development or released as experimental.Have feedback? Join the Early Access community to share your thoughts and help shape the feature.
This page covers enabling semantics in the Flutter runtime so your Rive graphics are accessible to screen readers. To learn what semantics are and how to add them to a graphic, see the Semantics editor documentation.

Overview

In the Rive Editor, you can add semantic meaning to certain elements of your graphic-roles such as button, checkbox, tab, image, list, dialog, and more. Alongside these roles, you can add associated labels, values, states, and actions. These settings vary per role. The Flutter runtime reads those semantics from the running state machine and projects them into Flutter’s semantics tree. Each Rive semantic node becomes a Flutter semantics node with the matching role, flags, and actions, positioned over the element it describes and kept in sync as the state machine advances. The graphic itself is painted pixels, opaque to assistive technologies, so this projected tree is what makes it discoverable. The runtime also forwards screen reader actions back to the state machine, such as tapping a button, stepping a slider, or moving accessibility focus.
Semantics are opt-in. The default mode is RiveSemantics.disabled, so no semantic tree is queried or built until you enable semantics.
Semantics must be defined in the editor to have any effect. If an element has no semantics, it is not exposed to screen readers, regardless of the mode you set. See Feature Support for which runtimes currently support semantics.

Requirements

  • rive version 0.15.0 or later. RiveWidget.semantics is not available in 0.14.x.
  • Flutter 3.32.0 or later (Dart 3.8.0), which is the rive package minimum.

Semantics modes

Semantics are controlled by the semantics parameter of RiveWidget, which takes a RiveSemantics mode such as RiveSemantics.auto:
Activation is one way. Once semantics are enabled, the controller keeps tracking them until it is disposed, so switching back to RiveSemantics.disabled removes the semantic nodes but does not stop the tracking.

Usage

Pass semantics when you build your RiveWidget.
Semantics work the same way when drawing into a shared texture with useSharedTexture or sharedTexture.

Activating only for screen reader users

Use RiveSemantics.auto so nothing is queried or built until the platform asks for accessibility. This is the best default for most apps, since it does no work at all for users who never turn on a screen reader.
On web, the platform requests accessibility when the user activates the page’s hidden “Enable accessibility” element, not at startup.

How semantics map to Flutter

The runtime translates each editor semantic role into the matching Flutter semantics role, flags, and actions.
This set of roles and traits may be subject to change while the semantic feature is in early access.
States and traits map to the matching Flutter semantics flags, such as enabled, expanded, selected, checked, toggled, and required. A flag is only set when the corresponding trait is present in the editor, so assistive technologies see “not applicable” rather than “false”.
  • Label, Hint, and Value map to the node’s label, hint, and value.
  • Hidden hides the node from assistive technologies.
  • Live Region marks the node as a live region, so changes are announced.

Testing semantics

Rive semantics go through Flutter’s own accessibility support, so test with the screen readers Flutter supports:
  • Android: TalkBack
  • iOS / macOS: VoiceOver
  • Windows: Narrator or NVDA
  • Linux: Orca
  • Web: the screen reader of the host platform, such as VoiceOver on macOS and iOS, TalkBack on Android, or NVDA or JAWS on Windows
Turn one on and navigate through your graphic after enabling semantics at runtime. Check that each element announces a clear label, the correct role, and an accurate value and state, and that navigation follows a logical order. Setting showSemanticsDebugger: true on your MaterialApp draws the generated tree on screen. Flutter only builds a semantics tree once the platform asks for one, which on web means the user activating the hidden “Enable accessibility” element. Call SemanticsBinding.instance.ensureSemantics() to build it yourself, either to inspect it without a screen reader or to skip that step for your users, and hold the returned handle for as long as you need it. For a full checklist, see Testing Semantics in the editor documentation.