Lottie JSON file from Sanity not rendering in lottie-react component
The issue you're experiencing is that lottie-react's animationData prop expects the actual JSON object data, not a URL string. When you pass props.node.document.url, you're giving it the URL path to the file, but Lottie needs the parsed JSON content.
The Solution: Fetch and Parse the JSON
You need to fetch the JSON file from the URL first, then pass the parsed data to the animationData prop:
lottieFile: (props) => {
const [animationData, setAnimationData] = React.useState(null);
const url = props.node.document.url;
React.useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => setAnimationData(data))
.catch(error => console.error('Error loading Lottie:', error));
}, [url]);
const styles = {
width: 500,
height: 500
};
if (!animationData) return <div>Loading animation...</div>;
return <Lottie animationData={animationData} style={styles} />;
}This approach:
- Fetches the Lottie JSON file from the Sanity CDN URL
- Parses it into a JavaScript object
- Passes that object to the
animationDataprop (which is what lottie-react expects) - Handles loading states while the file is being fetched
Important: Verify Your URL Structure
Based on the Sanity file type documentation, when querying file assets, you need to dereference them properly to get the URL. Make sure your GROQ query includes:
// In your query
"lottieFile": {
"url": asset->url
}If you're accessing it through props.node.document.url in your serializer, verify that your schema and query are properly set up to include the dereferenced asset URL. The asset field in a file type is a reference that needs to be dereferenced with the -> operator.
Alternative: useLottie Hook
If you need more control over the animation (play/pause, speed, etc.), you can use the useLottie hook instead:
lottieFile: (props) => {
const [animationData, setAnimationData] = React.useState(null);
const url = props.node.document.url;
React.useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => setAnimationData(data))
.catch(error => console.error('Error loading Lottie:', error));
}, [url]);
const options = {
animationData: animationData,
loop: true,
autoplay: true,
};
const { View } = useLottie(options);
if (!animationData) return <div>Loading animation...</div>;
return <div style={{ width: 500, height: 500 }}>{View}</div>;
}The key takeaway: animationData expects a JSON object, not a URL path, so you must fetch and parse the file first before passing it to the Lottie component.
Show original thread3 replies
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.