Next.js Discord

Discord Forum

Not able to render Rive animation in loading.tsx with Nextjs14 with App router

Answered
Araucanian herring posted this in #help-forum
Open in Discord
Araucanian herringOP
Hi, I tried to follow also all Rive documents and this blog
https://rive.app/community/doc/preloading-wasm/docZkAViuNLJ
https://dev.to/alex_barashkov/optimization-techniques-for-rive-animations-in-react-apps-1a8p

I'm able to load it within page.tsx.. just not in loading.tsx
I've added to my public folder rive/loader.riv and rive/rive.wasm
this is what I have for now:

Loader.tsx:
"use client";

import { useRive } from "@rive-app/react-canvas";

export default function Loader() {
const { RiveComponent } = useRive({
src: "/rive/loader.riv",
autoplay: true,
});

return (
<div className="flex justify-center">
<RiveComponent style={{ width: "300px", height: "300px" }} />
</div>
);
}

in layout.tsx I've added this:
<head>
<link
rel="preload"
href="/rive/rive.wasm"
as="fetch"
crossOrigin="anonymous"
/>
<link
rel="preload"
href="/rive/loader.riv"
as="fetch"
crossOrigin="anonymous"
/>
</head>

loading.tsx:
import Loader from "@/components/Loader";

export default function Loading() {
return (
<div className="flex items-center border-2 border-solid border-red-500">
<div className="flex items-center justify-center h-screen">
<Loader />
</div>
</div>
);
}


page.tsx:
export default async function Page() {
await new Promise((resolve) => setTimeout(resolve, 5000));
return <div>Hello World2k</div>;
}
Answered by alfonsus
Loading.tsx is loaded from a suspense boundary. As such, it is actually send to the user and rendered BEFORE any JS has loaded. If you have any script that relies on browser javascript, those will only run after the browser finished suspending.
View full answer

20 Replies

Araucanian herringOP
forgot to say also In layout.tsx I have
import { RuntimeLoader } from "@rive-app/react-canvas";
RuntimeLoader.setWasmUrl("/rive/rive.wasm");
@Araucanian herring Hi, I tried to follow also all Rive documents and this blog https://rive.app/community/doc/preloading-wasm/docZkAViuNLJ https://dev.to/alex_barashkov/optimization-techniques-for-rive-animations-in-react-apps-1a8p I'm able to load it within page.tsx.. just not in loading.tsx I've added to my public folder rive/loader.riv and rive/rive.wasm this is what I have for now: **Loader.tsx:** "use client"; import { useRive } from "@rive-app/react-canvas"; export default function Loader() { const { RiveComponent } = useRive({ src: "/rive/loader.riv", autoplay: true, }); return ( <div className="flex justify-center"> <RiveComponent style={{ width: "300px", height: "300px" }} /> </div> ); } **in layout.tsx I've added this:** <head> <link rel="preload" href="/rive/rive.wasm" as="fetch" crossOrigin="anonymous" /> <link rel="preload" href="/rive/loader.riv" as="fetch" crossOrigin="anonymous" /> </head> **loading.tsx:** import Loader from "@/components/Loader"; export default function Loading() { return ( <div className="flex items-center border-2 border-solid border-red-500"> <div className="flex items-center justify-center h-screen"> <Loader /> </div> </div> ); } **page.tsx:** export default async function Page() { await new Promise((resolve) => setTimeout(resolve, 5000)); return <div>Hello World2k</div>; }
Loading.tsx is loaded from a suspense boundary. As such, it is actually send to the user and rendered BEFORE any JS has loaded. If you have any script that relies on browser javascript, those will only run after the browser finished suspending.
Answer
Loading.tsx is a feature of React's Suspense behavior and React's suspense behavior is a feature of partially rendering the html before the full content arrived and load any necessary js inside the incoming components
Araucanian herringOP
I understand.. what options do I have than if I want to render this kind of loader in loading.tsx? do I must use client component and handle this loader not in loading.tsx?
yes you have to use client component and handle those loader not in loading.tsx
Araucanian herringOP
I see.. well thank you:)
though it's not the answer I've hoped for hehe..
this means that if I want a loading.tsx with web/js support. I must create all the pages with client component
yeah, it just sadly aren't meant to do full loading feature but just as a mere: "this is what to display while everything else is being loaded to client's browser"
which is why it needs to be lightweight
i can imagine if you have your loading animations with CSS/SVG animations then it should work 👀
Araucanian herringOP
I'll see if I can create this loader with css&svg.. though Rive is pretty nit:)
anyway thank you for all the help:)
appreciate it!:100vercel:
Araucanian herringOP
I've exported it as GIF and it works;) (SVG costs money)
GIF is too bad for performancec
gif for whole screen loading animation.. UHH
Araucanian herringOP
yeah I decided not to go with it heh.. doing skeleton instead.. but now I have a problem checking if it's mobile or not (again issue with loading.tsx?:X)
Araucanian herringOP
i have like timeline + content; in mobile I don't want the content and having trouble not to show it in the skeleton:X
what's the trouble? media query and display: none
what's that difficult to hide content in the mobile?
Araucanian herringOP
yes you right:X thank you James:)