rive-integration-core
Reactive icon

Rive Integration Core

Stable version 1.0.0 (Compatible with OutSystems 11)
Uploaded
 on 9 May (11 days ago)
 by 
0.0
 (0 ratings)
rive-integration-core

Rive Integration Core

Documentation
1.0.0

What this is

This Forge asset is a learning resource, not a reusable component. It demonstrates one approach to integrating Rive animations into an OutSystems Reactive Web application using a friendly login bear example.

You are not expected to consume the LoginBear block as a dependency in your own apps. The block, the script, and the wiring are tightly coupled to this specific animation file and login flow. Treat them as a worked example: read the source, understand the moving parts, and copy the bits you need into your own module to fit your own animation and use case.

If you happen to want exactly this bear behaving in exactly this way, you can use the block as-is, but the more common path is to fork it as a starting point.


How to use this asset

  1. Install the asset and open the RiveIntegration module in Service Studio.
  2. Run the demo screen to see the animation in action (RiveIntegrationDemo).
  3. Read the inline comments in RiveLoginBear.js (under the Scripts folder) and the LoginBear block's lifecycle handlers.
  4. In your own module, recreate the parts you need (see the recipe below) and adapt them to your animation.

There is intentionally no "add the block as a dependency and you're done" path here. Rive integration involves a .riv file (renamed to .bin so Service Studio can understand it) specific to your design, state machine inputs unique to your animation, and DOM elements unique to your UI, none of which generalize cleanly across apps.


What's in the demo

  • RiveLoginBear.js (Scripts folder) — A JavaScript class that loads the Rive runtime, instantiates the animation on a canvas, wires DOM event listeners to state machine inputs, and exposes methods to fire triggers. This is the heart of the integration.
  • LoginBear block — The UI: a canvas, a username input, a password input, and a login button. Its OnReady calls RiveLoginBear.create(...) and its OnDestroy calls destroy() to clean up.
  • TriggerSuccess / TriggerFail client actions — Thin wrappers that look up the active RiveLoginBear instance and call the corresponding trigger method.
  • login-teddy.bin — The Rive animation file, included as a module resource (see Credits in the description for licensing).


How to integrate Rive into your own OutSystems app

Use the demo as a recipe. Here are the moving parts you'll need to recreate in your own module, in roughly this order.

1. Get your Rive animation file

Export your animation from the Rive editor and rename it to a ".bin" file. In Service Studio, add it as a Resource to your module with Deploy Action: Deploy to Target Directory. The file will be served from a URL like /YourModuleName/your-animation.bin.

Note the names of your state machine and its inputs (booleans, numbers, triggers) — you'll need them in the JavaScript.

2. Create the JavaScript class

Copy RiveLoginBear.js from the demo into your own module's Scripts folder and adapt it. The key things to change:

  • RIVE_CDN — leave as-is, or download rive.min.js and add it as a script resource if your environment's Content Security Policy blocks external CDNs.
  • RIVE_FILE_URL — point to your own .bin resource path.
  • STATE_MACHINE_NAME — match the state machine name in your Rive file.
  • The inputs object inside _onRiveLoaded — replace isChecking, isHandsUp, numLook, trigSuccess, trigFail with the input names from your state machine.
  • The DOM event listeners in _attachListeners — replace the focus/blur/input wiring with whatever your UI needs (clicks, hover, scroll, form changes, anything).

The two parts you should keep verbatim unless you really know what you're doing:

  • The loadRuntime static method, including the window.define = undefined workaround. This handles the AMD/UMD conflict caused by OutSystems' script loader and is the most common reason Rive integrations silently fail in OutSystems.
  • The prefers-reduced-motion check. Honoring user accessibility preferences is the right default.

3. Create the block

Build a Reactive block with:

  • A <canvas> (use an Unescaped HTML widget with <canvas></canvas>).
  • Whatever interactive widgets your animation reacts to (inputs, buttons, etc.).
  • An OnReady event that calls your equivalent of RiveLoginBear.create(...), passing the IDs of the root container and the interactive widgets as parameters.
  • An OnDestroy event that looks up the instance and calls destroy() to release the canvas and remove listeners.

Add your script to the block's Required Scripts so the platform loads it before OnReady runs.

4. Expose triggers as client actions (optional)

If your animation has trigger inputs you want to fire from OutSystems logic — for example, after a server action returns success or failure — wrap them in client actions that look like:

const instance = YourClass.get($parameters.RootId);
if (instance) instance.triggerSuccess();

This keeps consumers of your block in OutSystems-land.

Things worth knowing before you start

OutSystems and AMD modules. The Rive runtime is distributed as a UMD bundle. OutSystems pages have an AMD loader (define.amd) globally available, which causes UMD bundles to register as anonymous AMD modules instead of attaching to window.rive. The result: window.rive is undefined even though the script loaded successfully. The fix is to temporarily set window.define = undefined while the Rive script loads, then restore it. The demo's loadRuntime method does this.

OnReady can fire more than once. Reactive Web's OnReady can re-run on the same block instance (after async data, navigation, etc.). The class handles this by destroying any previous instance attached to the root element before creating a new one. If you skip that guard, you'll leak event listeners and Rive instances on every re-render.

State machine triggers aren't queued. If you fire a trigger while the state machine is mid-transition from another state, the trigger may be silently dropped because no transition in the current state listens for it. The demo demonstrates this limitation (focus the password field, then immediately click Login — the success animation often won't play). The cleanest fix lives in the Rive file itself: add transitions from every interactive state directly to your success/fail states. A JavaScript-side workaround using EventType.StateChange is also possible.

Reduced motion. The demo respects prefers-reduced-motion and skips starting the state machine when it's enabled. You should keep this in your own integration — animations can cause real distress for some users, and respecting the OS setting is a one-line check.

Troubleshooting (in your own integration)

The animation doesn't appear and the console shows "Rive runtime is not available." window.rive is undefined. Check that your loadRuntime method includes the window.define = undefined workaround, and that you're calling it before trying to construct a Rive instance.

The animation loads but doesn't react to user input. The widget IDs you passed to the class don't resolve to the actual <input> elements. OutSystems sometimes places IDs on a wrapper rather than the input itself. The demo's resolveInputElement helper handles this — make sure you keep it (or its equivalent) in your version.

Triggers don't play the animation. Either the trigger name in JavaScript doesn't match the input name in the Rive file (case-sensitive), or the state machine has no transition listening for that trigger from its current state. Check both. In DevTools, you can inspect document.querySelector("#YOUR_ROOT_ID").__riveLoginBear.inputs to see what got wired up.

The Rive script doesn't load at all. Check the Network tab. If the request to the CDN is blocked, your environment's Content Security Policy probably doesn't allow cdn.jsdelivr.net. Either whitelist it in Service Center, or download rive.min.js and add it as a script resource in your module.

Source code

The JavaScript class is heavily commented. Open RiveLoginBear.js in the Scripts folder of the RiveIntegration module and read it top-to-bottom, it's the most useful part of this asset.