sanity-plugin-rive
v0.1.1
Published
Sanity Studio plugin for uploading and previewing Rive animation files
Downloads
199
Maintainers
Readme
Features
- Registers a
riveFileschema type restricted to.rivfiles - Live animation preview inside the Studio with play/pause and restart controls
- State machine input controls (booleans, numbers, triggers) in the preview panel
- Drag-and-drop upload support
- Optional
RiveFromSanityReact component for rendering on the frontend
Installation
npm install sanity-plugin-rive @rive-app/canvasSetup
Add the plugin to your sanity.config.ts:
import {defineConfig} from 'sanity'
import {rivePlugin} from 'sanity-plugin-rive'
export default defineConfig({
// ...
plugins: [
rivePlugin(),
],
})Usage in schemas
Use the riveFile type in any document schema:
import {defineType, defineField} from 'sanity'
export default defineType({
name: 'page',
title: 'Page',
type: 'document',
fields: [
defineField({
name: 'animation',
title: 'Animation',
type: 'riveFile',
}),
],
})The riveFile type is a Sanity file type restricted to .riv files. It includes a custom input component that previews the animation inside the Studio with playback controls and state machine input UI.
Querying with GROQ
Query the Rive file field as-is — RiveFromSanity handles the reference resolution for you:
*[_type == "page"][0] {
animation
}That's it. Pass the result directly to <RiveFromSanity data={animation} />.
If you need the CDN URL directly (e.g. for @rive-app/canvas or server-side use), expand the asset reference:
*[_type == "page"][0] {
animation {
asset-> {
_id,
url
}
}
}Frontend rendering
Option A: Use the built-in RiveFromSanity component
This plugin ships an optional RiveFromSanity component under the sanity-plugin-rive/react subpath. It requires @rive-app/react-canvas as a peer dependency:
npm install @rive-app/react-canvas'use client'
import {RiveFromSanity, type SanityRiveData} from 'sanity-plugin-rive/react'
export function MyAnimation({animation}: {animation: SanityRiveData}) {
return (
<RiveFromSanity
data={animation}
projectId="your-project-id"
dataset="production"
style={{width: '100%', height: 400}}
/>
)
}The data prop accepts both expanded asset objects (from asset->) and raw references. By default, the component auto-detects and plays the first state machine in the .riv file when you do not provide explicit playback options.
State machines
By default, RiveFromSanity auto-plays the first state machine found in the file. To target a specific state machine, pass the stateMachines prop:
// Specific state machine
<RiveFromSanity data={animation} stateMachines="State Machine 1" ... />
// Multiple state machines
<RiveFromSanity data={animation} stateMachines={["State Machine 1", "Hover"]} ... />Timeline animations
If your .riv file relies on a looping timeline animation, pass the animations prop so the helper does not override it with the first detected state machine:
<RiveFromSanity data={animation} animations="Loop" ... />State machine looping is authored inside Rive itself, so the frontend helper cannot force an arbitrary state machine to loop the way it can select a timeline animation to autoplay.
For additional control, use the riveOptions prop to pass any option supported by @rive-app/react-canvas:
<RiveFromSanity
data={animation}
riveOptions={{autoplay: false}}
...
/>That includes options such as artboard, layout, onPlay, onPause, onLoop, onStateChange, and animations if you prefer to keep everything inside riveOptions.
Option B: Use @rive-app/react-canvas directly
For full control, use @rive-app/react-canvas (or the vanilla @rive-app/canvas) directly. You can resolve the CDN URL from a file reference using the resolveRiveFileUrl helper:
'use client'
import {useRive} from '@rive-app/react-canvas'
import {resolveRiveFileUrl} from 'sanity-plugin-rive'
interface RiveAnimationProps {
fileRef: string // e.g. "file-abc123-riv"
projectId: string
dataset: string
}
export function RiveAnimation({fileRef, projectId, dataset}: RiveAnimationProps) {
const src = resolveRiveFileUrl(fileRef, {projectId, dataset})
const {RiveComponent} = useRive({
src,
autoplay: true,
stateMachines: 'State Machine 1',
})
return <RiveComponent style={{width: '100%', height: '400px'}} />
}If you query asset->url via GROQ, you can pass that URL directly as src without any client-side resolution.
Exports
| Export path | Contents |
|---|---|
| sanity-plugin-rive | rivePlugin, riveFileType, resolveRiveFileUrl |
| sanity-plugin-rive/react | RiveFromSanity component, resolveRiveFileUrl (requires @rive-app/react-canvas) |
License
MIT
