How to Add a Rive Mascot in Bolt.new, v0 and Replit
By the Charmotion team · Updated

Bolt.new, v0 and Replit all build JavaScript apps and install npm packages when asked, so the Rive route is the same: install @rive-app/react-webgl2, add the .riv as a static file, and render it in one fixed-size component. Only the upload differs: Bolt's Code view, v0's chat attachments, which accept .riv files, and Replit's chat upload or an external host.
Key takeaways
- One prompt and one component work in all three; only the file upload step differs.
- In Bolt, drag the .riv into the Public folder in Code view; chat attachments aren't saved to the project.
- v0 lists RIV among its supported attachment types and starts new chats on Next.js, so App Router rules apply.
- Replit's App Storage buckets are private with expiring signed URLs, so serve a public .riv from the app's static folder or a CDN.
- Check the .riv request returns 200 before debugging names or code.
Already have a character or logo? See your character in real app screens: splash, onboarding, loading and empty-state screens. It's free, runs in your browser and uploads nothing.
How do Bolt, v0 and Replit differ for a Rive mascot?
The code is the same React component everywhere. The builders differ in their default stack and in how a binary file gets into the project:
| Builder | Stack | Getting the .riv in | Watch out for |
|---|---|---|---|
| Bolt.new | JavaScript apps in the browser (WebContainers), most popular frameworks | Code view: drag into the Public folder | Chat attachments are used temporarily, not saved |
| v0 | Next.js with shadcn/ui and Tailwind for new chats | Attach the .riv in chat; RIV is a listed type | App Router: client-only component |
| Replit | Whatever the Agent scaffolds; check package.json | Upload in chat and ask the Agent to save it to the static folder, or use a CDN URL | App Storage is private, with signed URLs |
All three install npm packages when you ask, so @rive-app/react-webgl2 is a one-line request. If your project uses a framework other than React, use Rive's web runtime @rive-app/webgl2 directly instead.
How do I add a .riv file in Bolt.new?
Use Code view, not the chat. Bolt's docs say a file attached in the chatbox is used for that request but isn't permanently added to the project, while a file added in Code view is stored in the project files.
- Click the
<>icon to open Code view. - Expand the Public folder and drag
mascot.rivinto it. - Right-click the file and choose Copy Relative Path.
- Paste the prompt from the last section, using
/mascot.rivas the URL.
Bolt's list of supported file types names images, documents, code and data files but not .riv. If Code view refuses the file, host it on a CDN with CORS and give Bolt the URL. Files can be up to 10 MB on the free plan and 100 MB on paid plans.
If your Bolt project is a mobile app built with Expo, the web packages don't apply. Rive's React Native runtime needs a development build; see Rive in Expo.
What changes in v0, which builds Next.js?
Two things: v0 accepts the file directly, and the project is Next.js. v0's upload docs list RIV among supported attachment types, alongside images, video, fonts and 3D models. Chat attachments can be up to 5 MB on the free plan and 20 MB on paid plans. Attach mascot.riv with the + icon and say where it goes:
Save the attached mascot.riv as public/mascot.riv and load it from /mascot.riv.
New v0 chats start with a Next.js app using shadcn/ui and Tailwind, and v0 builds backends with App Router conventions. So the mascot must be a Client Component with "use client", imported by a Server Component page, and browser checks such as matchMedia belong in effects. If a build reports window is not defined, ask v0 to load the component with next/dynamic and ssr: false from inside a Client Component. The details, including self-hosting rive.wasm at the right version, are in Rive in the Next.js App Router.
How do I add the .riv in Replit?
Replit's docs describe uploading through the chat: click the plus button in the prompt box and choose Upload a file, or drag the file into the prompt box. Then tell the Agent where it belongs:
Save the attached mascot.riv into the front end's static assets folder
(public/ for Vite or Next.js) so it is served at /mascot.riv in the
published app. Then confirm the path.
Don't use App Storage as a public host for the mascot. Replit says App Storage buckets are always private, and links to their files are signed URLs that expire, which suits user uploads, not a file every visitor's browser fetches. The static folder or an external CDN with CORS is the right home.
Before you publish, open the preview's network tab and confirm /mascot.riv returns 200. Then check the published app the same way, since the static folder is what ships.
Which prompt works in all three builders?
Give the builder the file's names and the rules that prevent the common failures. This prompt assumes a file with a Character view model; rename the properties to match yours:
Add an animated mascot component.
- Install @rive-app/react-webgl2 (pin the exact version you install).
- The file is /mascot.riv (in public/). State machine: "CharacterViewModelMachine".
Use useRive with autoplay: true and autoBind: true.
- View model "Character": number "mood" (0 idle, 1 happy, 2 wave, 3 thinking,
4 sad, 5 loading, 6 listening, 7 talking, 8 sleeping, 9 attention) and triggers
"success", "error", "yes", "no", "enter", "exit".
- Create components/Mascot.tsx with props mood: number and celebrateKey: number.
Set mood with useViewModelInstanceNumber("mood", rive?.viewModelInstance) in a
useEffect; fire useViewModelInstanceTrigger("success", ...) when celebrateKey
increases.
- Wrap RiveComponent in a div with a fixed 240 x 240 px size (no layout shift).
- If prefers-reduced-motion is reduce, render /mascot-poster.webp instead.
- Render it only in the browser (client-only), never during server rendering.
- Do not add Lottie or any other animation library.
The names in that prompt match a Charmotion file, which ships CharacterViewModelMachine with the Character view model, a classic CharacterStateMachine with a mood input for older code, and a LaunchStateMachine intro that fires no end event (time it at about 2.6 seconds). The .riv comes with every paid plan (from $20 a month).
For splash screens and loading intros in the same tools, see AI prompts for an animated splash or loading mascot.
How do I check the result before publishing?
AI builders often produce code that looks right and renders nothing. Check in this order, because each step rules out the next:
- The file loads. The network tab shows
mascot.rivwith status 200. A 404 means the path is wrong (/mascot.riv, not/public/mascot.riv); a CORS error means the host needsAccess-Control-Allow-Origin. - The names match. The state machine and property names in the code match the file exactly, including case.
- The box has a size. The wrapper has an explicit width and height.
- Values are set in effects. No Rive calls run during render.
- Reduced motion. With the OS setting on, the page shows the poster instead.
- Versions are pinned.
package.jsonlists an exact Rive version, notlatest.
Add a Rive mascot in Bolt.new, v0 or Replit
- Install the runtime. Ask the builder to install @rive-app/react-webgl2 and pin the exact version.
- Add the .riv. Bolt: drag it into Public in Code view. v0: attach it and ask to save it as public/mascot.riv. Replit: upload in chat and ask the Agent to save it to the static folder.
- Paste the prompt. Give the state machine, view model and property names, a fixed-size wrapper, reduced motion and client-only rendering.
- Apply framework rules. In v0 or any Next.js project, keep the mascot in a "use client" component and browser checks in effects.
- Check the result. Confirm the .riv returns 200, names match, the wrapper has a size, and versions are pinned.
Frequently asked questions
Can I upload a .riv file to v0?
Yes. v0's upload docs list RIV among the supported attachment types. Attach it with the + icon or drag it into the chat, then ask v0 to save it as public/mascot.riv. Attachments can be up to 5 MB on the free plan and 20 MB on paid plans.
Why doesn't Bolt keep the file I attached in chat?
Bolt's docs say chatbox attachments are used for that request but aren't permanently added to your project files. To keep a file, add it in Code view, for example by dragging it into the Public folder, then reference its path in your prompt.
Can I host the mascot file in Replit App Storage?
It isn't a good fit. Replit says App Storage buckets are always private, and links to their files are signed URLs that expire. A mascot that every visitor loads belongs in the app's static folder or on a CDN that sends CORS headers.
Quick answers from this guide
Sources
- Attach files to your project, Bolt Support
- bolt.new README, StackBlitz on GitHub
- Expo for mobile apps, Bolt Support
- Images, videos, and file uploads, v0 Docs
- Full-stack apps, v0 Docs
- Upload and use files, Replit Docs
- App Storage, Replit Docs
- React runtime, Rive
- React runtime: Data binding, Rive