Export the animation, upload the file next to your site, and play it with a small open-source player. This page has the code to copy, and the handful of things worth checking before it goes live. For mobile apps, jump to step 6.
The short version. Export Lottie JSON,
host it on your own site, and play it with
lottie-web using the
canvas renderer. The snippet in step 3 does exactly that.
Open Export and choose one of two files:
Lottie JSON plays in every Lottie player. If you're not
sure, this is the one.
.lottie is the same animation in a smaller
package, for players that support it — see
step 4.
On the free plan the file carries a small watermark; a paid plan exports without it. If the animation is going on a client's site, export it from a plan that removes the watermark.
Upload the exported file with the rest of the site's static files, for
example to /animations/hero.json. Link to that copy, never
to a download link from the app. Some site builders refuse
.json or .lottie uploads in their media library;
if yours does, put the file in the site's own files or on a CDN you
control.
This works on any site where you can paste HTML — hand-written pages, WordPress, Webflow, Squarespace and similar, through a custom code or embed block. Set the width and height on the container to match the animation's shape so the page doesn't jump when it loads.
<div id="hero" style="width:100%;max-width:400px;aspect-ratio:4/3"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.13.0/lottie_canvas.min.js"></script>
<script>
var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
lottie.loadAnimation({
container: document.getElementById('hero'),
renderer: 'canvas',
loop: true,
autoplay: !reduceMotion, // visitors who ask for less motion get the first frame
path: '/animations/hero.json'
});
</script>
The version number is pinned on purpose. Keep it, so a player update
can't change how your animation looks. lottie_canvas.min.js
is the smaller build that contains only the canvas renderer.
.lottie file
Use the .lottie export with the dotLottie player when the
smaller download matters.
<canvas id="hero" width="400" height="300" style="width:100%;max-width:400px;height:auto"></canvas>
<script type="module">
import { DotLottie } from 'https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-web@0.80.0/+esm';
new DotLottie({
canvas: document.getElementById('hero'),
src: '/animations/hero.lottie',
loop: true,
autoplay: !window.matchMedia('(prefers-reduced-motion: reduce)').matches
});
</script>
Set the canvas width and height to the
animation's own size — the artboard size in the editor. dotLottie draws with a
different engine from lottie-web, so give your animation a look in it
before you ship. If anything looks different from the editor, use the
Lottie JSON file with lottie-web instead.
Install the player with npm install lottie-web@5.13.0, then:
import { useEffect, useRef } from 'react';
import lottie from 'lottie-web/build/player/lottie_canvas';
export function Animation({ src, ...props }) {
const box = useRef(null);
useEffect(() => {
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const anim = lottie.loadAnimation({
container: box.current,
renderer: 'canvas',
loop: true,
autoplay: !reduceMotion,
path: src
});
return () => anim.destroy();
}, [src]);
return <div ref={box} {...props} />;
}
// <Animation src="/animations/hero.json" style={{ width: 400, maxWidth: '100%' }} />
Put the file in your public folder, or wherever your
framework serves static files from, so src is a plain URL.
canvas renderer. It's the one we
test against, and it's what the editor itself uses for MP4 and image
exports, so what you see in the editor is what it draws.
role="img" and an aria-label, or
leave it out if the animation is purely decorative.
Where a Lottie player can't go — social posts, slide decks, email — export MP4 instead. It's made from the same animation.
For iOS, Android, Flutter and React Native, the Lottie project publishes
an official player for each, and we've tested all of them — see
Player support for exactly what each one
draws. Use the Lottie JSON export in every
snippet below, and put the file in your project as animation.json.
The versions shown are the ones we tested.
Add the library:
dependencies {
implementation("com.airbnb.android:lottie:6.7.1")
}
Save the file as app/src/main/res/raw/animation.json (the name
must be lowercase), then add the view to a layout. The root element needs
xmlns:app="http://schemas.android.com/apk/res-auto".
<com.airbnb.lottie.LottieAnimationView
android:layout_width="200dp"
android:layout_height="200dp"
app:lottie_rawRes="@raw/animation"
app:lottie_autoPlay="true"
app:lottie_loop="true" />
We haven't checked .lottie files on Android. See
what to watch for on Android.
Compose uses a separate library, at the same version:
dependencies {
implementation("com.airbnb.android:lottie-compose:6.7.1")
}
With the file in res/raw/animation.json as above:
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.rememberLottieComposition
@Composable
fun Animation() {
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.animation))
LottieAnimation(
composition = composition,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(200.dp),
)
}
The support-page results were measured through the standard Android view, not through Compose. Compose draws with the same engine, but check the result in your app.
In Xcode choose File ▸ Add Package Dependencies…,
paste https://github.com/airbnb/lottie-ios.git and pick version
4.6.0. Drag animation.json into your project with your app
target ticked, then:
import Lottie
import SwiftUI
struct AnimationView: View {
var body: some View {
LottieView(animation: .named("animation"))
.looping()
.frame(width: 200, height: 200)
}
}
The iOS results on the Player support page were measured in the iOS Simulator. We haven't built this exact snippet, so check it in your app. See what to watch for on iOS.
Add the package with flutter pub add lottie, and list the file as an asset:
flutter:
assets:
- assets/animation.json
import 'package:lottie/lottie.dart';
Lottie.asset('assets/animation.json', width: 200, height: 200)
If your animation contains a picture, this package doesn't draw it by default. Load the file yourself and decode the pictures first:
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:lottie/lottie.dart';
Future<LottieComposition> loadWithPictures(String path) async {
final data = await rootBundle.load(path);
final composition = await LottieComposition.fromBytes(data.buffer.asUint8List());
for (final image in composition.images.values) {
final at = image.fileName.indexOf('base64,');
if (image.fileName.startsWith('data:') && at > 0) {
image.loadedImage =
await decodeImageFromList(base64Decode(image.fileName.substring(at + 7)));
}
}
return composition;
}
Then show it with Lottie(composition: composition, width: 200, height: 200),
for example inside a FutureBuilder. See
what to watch for on Flutter.
Run npm install lottie-react-native, then cd ios && pod install
for iOS. Put the file next to the component:
import LottieView from 'lottie-react-native';
export default function Animation() {
return (
<LottieView
source={require('./animation.json')}
autoPlay
loop
style={{ width: 200, height: 200 }}
/>
);
}
We tested this on Android. We haven't run a React Native app on iOS. The library's own installation notes list the React Native versions it supports. See what to watch for on React Native.
Whatever you build, test your animation in your app before you rely on it, and tell us if something renders differently.