lottie-react
Examples

Interactions

Hover, click and state recipes, ready to take.

Play on hover

Enter to play, leave to pause; pointer events cover mouse and touch:

import { LottieDisplay, useLottie } from "lottie-react";export function HoverPlay() {  const lottie = useLottie({ src: "/anim.json", loop: true });  return (    <LottieDisplay      lottie={lottie}      onPointerEnter={() => lottie.play()}      onPointerLeave={() => lottie.pause()}    />  );}

Play on click

Each press restarts from the top: seek, then play:

import { Lottie, type LottieHandle } from "lottie-react";import { useRef } from "react";export function PlayOnClick() {  const handle = useRef<LottieHandle>(null);  const restart = () => {    handle.current?.seek(0);    handle.current?.play();  };  return (    <Lottie      as="button"      src="/anim.json"      lottieRef={handle}      onClick={restart}      aria-label="Play from the top"    />  );}

Follow the cursor

The pointer's horizontal position across the element sets the frame: move left and right to scrub, and leaving rewinds:

import { LottieDisplay, useLottie } from "lottie-react";export function CursorFollow() {  const lottie = useLottie({ src: "/anim.json" });  return (    <LottieDisplay      lottie={lottie}      className="size-48 touch-none"      onPointerMove={(event) => {        const box = event.currentTarget.getBoundingClientRect();        lottie.seek({          percent: ((event.clientX - box.left) / box.width) * 100,        });      }}      onPointerLeave={() => lottie.seek(0)}    />  );}

seek clamps what it is given, so the edges need no guard of their own.

Segment on state

The playing range follows React state, so anything that sets the state steers the animation:

import { LottieDisplay, useLottie } from "lottie-react";import { useEffect, useState } from "react";const parts = {  grow: [0, 60],  settle: [60, 120],} as const;export function SegmentOnState() {  const [part, setPart] = useState<keyof typeof parts>("grow");  const lottie = useLottie({ src: "/anim.json", autoplay: true, loop: true });  const { playSegments } = lottie;  useEffect(() => {    playSegments(parts[part]);  }, [part, playSegments]);  return (    <>      <LottieDisplay lottie={lottie} />      <div>        <button type="button" onClick={() => setPart("grow")}>          grow        </button>        <button type="button" onClick={() => setPart("settle")}>          settle        </button>      </div>    </>  );}

On this page