Placing it yourself
Take over the layout with children, and change the element with as.
Give <Lottie> children and the layout is yours: it renders the wrapper, you place the parts.
The logo, placed by you
import { Lottie, LottieDisplay } from "lottie-react";export function YourOwnLayout() { return ( <Lottie src="/anim.json" autoplay loop> <p>The logo, placed by you</p> <LottieDisplay /> </Lottie> );}Place the display
With children present, <Lottie> no longer places the animation itself: render <LottieDisplay /> where it should draw.
Leave it out, or render two, and a development warning tells you.
<LottieDisplay> takes no children of its own.
The engine owns its contents and wipes them on every reload, so anything put inside would not survive.
Change the element
as renders <Lottie> as another tag:
import { Lottie, type LottieHandle } from "lottie-react";import { useRef } from "react";export function AsButton() { const handle = useRef<LottieHandle>(null); return ( <Lottie as="button" src="/anim.json" lottieRef={handle} onClick={() => handle.current?.play()} aria-label="Play the logo" /> );}The permitted tags are the ones that can legally hold the animation, and with children present, only tags that may hold a <div>.
An illegal choice is a compile error carrying the reason.
<LottieDisplay> takes as too.
Conditional children and inline tags
<Lottie as="span">{show && <Caption />}</Lottie> fails to compile even
while show is false, because the type sees children. Choose a block tag,
or lift the conditional outside.