DEV Community

Fazal Shah
Fazal Shah

Posted on

Using Lottie Animations in Next.js (App Router & Pages Router)

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
Enter fullscreen mode Exit fullscreen mode

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 }}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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 />;
}
Enter fullscreen mode Exit fullscreen mode

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 }} />;
}
Enter fullscreen mode Exit fullscreen mode

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)