Lottie animations are the best way to add crisp, lightweight animations to your Vue app. This guide covers the two main approaches in Vue 3.
Option 1: @lottiefiles/dotlottie-vue (Recommended)
The DotLottie package is the modern approach — smaller runtime (~100KB vs ~500KB), supports the newer compressed .lottie format, and has a clean Vue 3 API.
npm install @lottiefiles/dotlottie-vue
<template>
<DotLottieVue
src="/animations/loader.lottie"
:loop="true"
:autoplay="true"
style="width: 200px; height: 200px"
/>
</template>
<script setup>
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
</script>
For JSON files (not .lottie), use the same src prop pointing to your .json file.
Controlling Playback Programmatically
<template>
<DotLottieVue
ref="lottieRef"
src="/animations/check.lottie"
:loop="false"
:autoplay="false"
/>
<button @click="play">Play</button>
<button @click="pause">Pause</button>
</template>
<script setup>
import { ref } from 'vue'
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
const lottieRef = ref(null)
function play() {
lottieRef.value?.play()
}
function pause() {
lottieRef.value?.pause()
}
</script>
Option 2: lottie-web (Full Control)
For more granular control over frames, segments, and events:
npm install lottie-web
<template>
<div ref="container" style="width: 200px; height: 200px" />
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import lottie from 'lottie-web'
const container = ref(null)
let anim = null
onMounted(() => {
anim = lottie.loadAnimation({
container: container.value,
renderer: 'svg',
loop: true,
autoplay: true,
path: '/animations/loader.json',
})
})
onBeforeUnmount(() => {
anim?.destroy()
})
</script>
Always destroy the animation in onBeforeUnmount to prevent memory leaks.
Trigger Animation on User Interaction
A common pattern: play a success animation when a form submits.
<template>
<div ref="container" style="width: 100px; height: 100px" />
<button @click="handleSubmit">Submit</button>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import lottie from 'lottie-web'
import successData from '@/assets/success.json'
const container = ref(null)
let anim = null
onMounted(() => {
anim = lottie.loadAnimation({
container: container.value,
renderer: 'svg',
loop: false,
autoplay: false,
animationData: successData,
})
})
function handleSubmit() {
anim?.goToAndPlay(0)
}
onBeforeUnmount(() => anim?.destroy())
</script>
Global Registration (Nuxt / Large Apps)
Register once in a plugin so you don't import on every page:
// plugins/lottie.js
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.component('DotLottie', DotLottieVue)
})
Then use <DotLottie /> anywhere without importing.
Performance Tips for Vue
-
Lazy-load animation JSON outside your main bundle. Use dynamic imports or fetch in
onMounted. - Use .lottie format instead of JSON — ~80% smaller file size, loads faster.
-
Add
v-ifto mount/unmount the animation based on visibility, rather than hiding with CSS. - Set explicit dimensions on the container div — avoids layout shifts during load.
Free Lottie Animations for Your Vue App
You need a Lottie file to get started. Here are the best free sources:
- 500+ free animated icons: iconking.net/all-assets?type=lottie&price=free — UI icons, loaders, social icons, illustrations
- Preview before using: iconking.net/preview — drag-and-drop preview, no signup
- Customize colors/speed: iconking.net/editor — adapt any Lottie to your brand in-browser
- LottieFiles community: lottiefiles.com — large community library
Converting Lottie for Non-App Contexts
Need the same animation as a GIF for email, or MP4 for social? The free converter at iconking.net/tools/lottie-to-gif exports to GIF, MP4, WebM, SVG, WebP, APNG, or .lottie — all in the browser.
Top comments (0)