Adding Lottie to Next.js has one key gotcha: lottie-web and lottie-react are client-only libraries that access the DOM, so you need to handle SSR carefully. Here's how.
Step 1: Get Your Animation File
Download a free .json Lottie file from IconKing — preview and download with no signup. Save it to public/animations/ in your Next.js project so it's served as a static asset.
Step 2: Install lottie-react
npm install lottie-react
Step 3: Create a Client Component (App Router)
In Next.js App Router, any component using browser APIs must be a Client Component. Create components/LottieAnimation.tsx:
"use client";
import Lottie from "lottie-react";
import successAnim from "@/public/animations/success.json";
export default function LottieAnimation() {
return (
<Lottie
animationData={successAnim}
loop={true}
style={{ width: 200, height: 200 }}
/>
);
}
Then use it in any Server Component or page:
import LottieAnimation from "@/components/LottieAnimation";
export default function HomePage() {
return (
<main>
<h1>Welcome</h1>
<LottieAnimation />
</main>
);
}
Alternative: Dynamic Import (Zero SSR Bundle)
If you want to keep the animation completely out of the server bundle, use next/dynamic with ssr: false:
import dynamic from "next/dynamic";
const LottieAnimation = dynamic(
() => import("@/components/LottieAnimation"),
{ ssr: false, loading: () => <div style={{ width: 200, height: 200 }} /> }
);
export default function HomePage() {
return <LottieAnimation />;
}
This is the cleanest approach — the Lottie runtime only loads in the browser, keeping your server response fast.
Loading from a URL (Instead of Importing JSON)
For large files or dynamic animations fetched from an API, pass a URL via the path prop using lottie-web directly:
"use client";
import { useEffect, useRef } from "react";
import lottie from "lottie-web";
export default function RemoteLottie({ src }: { src: string }) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!ref.current) return;
const anim = lottie.loadAnimation({
container: ref.current,
renderer: "svg",
loop: true,
autoplay: true,
path: src,
});
return () => anim.destroy();
}, [src]);
return <div ref={ref} style={{ width: 200, height: 200 }} />;
}
Pages Router
If you're on the Pages Router, the "use client" directive is not needed — just use dynamic import with ssr: false and you're set.
Finding Free Animations
IconKing lets you preview, edit colors, and download free Lottie animations in both .json and .lottie formats — no account needed. It's the fastest way to go from "I need a loading spinner" to a production-ready asset.
Top comments (0)