Use a canvas ref and initialise Rive in onMounted. Works the same in Vue 3 and Nuxt.
Add the Rive WebGL runtime from npm.
npm install @rive-app/webglUse a template ref on a canvas element. Rive needs the real DOM, so onMounted is the right place.
<template>
<canvas ref="riveCanvas" width="150" height="150" />
</template>
<script setup>
import { onMounted, onUnmounted, ref } from "vue";
import { Rive } from "@rive-app/webgl";
const riveCanvas = ref(null);
let riveInstance = null;
onMounted(() => {
riveInstance = new Rive({
src: "/your_animation.riv",
canvas: riveCanvas.value,
autoplay: true,
artboard: "Main",
stateMachines: ["State Machine 1"],
});
})
onUnmounted(() => riveInstance?.cleanup())
</script>Store the Rive instance and call stateMachineInputs() to get the Hover and Clicked inputs.
<script setup>
import { onMounted, onUnmounted, ref } from "vue";
import { Rive } from "@rive-app/webgl";
const riveCanvas = ref(null);
let riveInstance = null;
let hoverInput = null;
onMounted(() => {
riveInstance = new Rive({
src: "/your_animation.riv",
canvas: riveCanvas.value,
autoplay: true,
stateMachines: ["State Machine 1"],
onLoad: () => {
const inputs = riveInstance.stateMachineInputs("State Machine 1");
hoverInput = inputs?.find((i) => i.name === "Hover");
}
});
})
function handleMouseEnter() { if (hoverInput) hoverInput.value = true; }
function handleMouseLeave() { if (hoverInput) hoverInput.value = false; }
onUnmounted(() => riveInstance?.cleanup())
</script>Does this work in Nuxt?
onMounted keeps Rive browser-only, so SSR won't try to run it. No extra Nuxt config needed.
webgl vs canvas runtime?
Both work. webgl is GPU-accelerated and better for complex animations. canvas is simpler. For icons, either is fine.
How do I clean up on unmount?
Call riveInstance.cleanup() in onUnmounted. The code above already does this.
Get your animated icons
Browse icons ready for Vue — free to download.