November 30, 2025
Animating Components in Nuxt with VueUse Motion

Md. Saad

Clean, fluid, and meaningful animations are essential for modern web applications, as they not only enhance the user experience but also add aesthetic appeal. Adding animation doesn't have to be difficult if you're using Nuxt 3. You can use a straightforward, composable-based API to animate your components while maintaining performance thanks to VueUse Motion.
This beginner-friendly tutorial covers installing VueUse Motion, configuring it within a Nuxt project, and animating your first components using an easy-to-understand syntax.
What Is VueUse Motion?
VueUse Motion is a lightweight animation library built on top of the popular VueUse ecosystem. It provides:
Easy-to-use animation composables
- Motion directives like v-motion
- Enter/leave transitions
- Scroll-based animations
- Preconfigured animations (fade, pop, slide, scale, etc.)
It’s a perfect fit for Nuxt 3 developers who want smooth UI interactions—without writing complex CSS or building custom animation logic.
Step 1: Install VueUse Motion in Your Nuxt 3 Project
Inside your Nuxt project, install the package:
npm install @vueuse/motionNuxt auto-imports most composables, but we still need to register the plugin manually.
Step 2: Create a Motion Plugin for Nuxt
Create your plugin file: plugins/motion.client.ts
import { MotionPlugin } from '@vueuse/motion'
import { defineNuxtPlugin } from '#app'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(MotionPlugin)
})Why .client.ts?
Animations are primarily browser-based and do not run on the server.
Step 3: Animate Your First Component with v-motion
Let’s animate a simple card component.
Example: Fade & Slide in on Mount
<template>
<div
v-motion
:initial="{ opacity: 0, y: 50 }"
:enter="{ opacity: 1, y: 0 }"
class="p-6 max-w-sm rounded-xl bg-white shadow"
>
<h2 class="text-xl font-semibold">Hello Motion!</h2>
<p class="text-gray-600">Nuxt + VueUse Motion = smooth animations.</p>
</div>
</template> What happens?
The card smoothly fades in and slides up when it enters the viewport.
Step 4: Using Motion Presets (Even Simpler)
VueUse Motion includes animated presets, so you don’t have to define your own transitions every time.
Example: Using the Built-In fadeIn Preset
<template>
<div v-motion-fade class="p-6 bg-green-200 rounded-lg">
This uses the fade preset.
</div>
</template>Other presets include:
- v-motion-pop
- v-motion-slide-left
- v-motion-slide-right
- v-motion-slide-up
- v-motion-slide-down
Step 5: Animate on Scroll (Scroll-Based Motion)
Want elements to animate when they appear on screen?
VueUse Motion includes intersection-based triggers built-in.
Example: Scroll Fade-In
<template>
<section class="space-y-10">
<div
v-motion
:initial="{ opacity: 0, y: 60 }"
:visible="{ opacity: 1, y: 0 }"
class="p-6 bg-blue-200 rounded-lg"
>
I animate when scrolled into view!
</div>
</section>
</template>- visible is triggered when the element becomes visible.
Step 6: Grouped or Staggered Animations
Animate lists with a natural, delayed sequence.
Example: Staggered Card Animation
<script setup>
const items = ['One', 'Two', 'Three']
</script>
<template>
<div class="space-y-4">
<div
v-for="(item, i) in items"
:key="i"
v-motion
:initial="{ opacity: 0, y: 40 }"
:enter="{ opacity: 1, y: 0, transition: { delay: i * 0.2 } }"
class="p-4 bg-white shadow rounded-lg"
>
{{ item }}
</div>
</div>
</template>Each item appears with a slight delay — clean and professional.
Step 7: Programmatic Animation with useMotion
If you need more power, use useMotion() to animate via composables.
Example:
<script setup>
import { useMotion } from '@vueuse/motion'
const box = ref(null)
const { apply } = useMotion(box, {
initial: { scale: 1 },
hovered: { scale: 1.1 },
})
</script>
<template>
<div
ref="box"
@mouseenter="apply('hovered')"
@mouseleave="apply('initial')"
class="w-32 h-32 bg-red-300 rounded-lg transition-all"
/>
</template>Great for interactive UI elements like buttons and cards.
Best Practices for Motion in Nuxt
- Use .client.ts when registering animation plugins
- Avoid overuse
- Use presets for consistency
- Combine with Tailwind for styling
- Test performance on mobile devices
Conclusion
VueUse Motion makes animating components in Nuxt 3 elementary and expressive. Whether you’re adding subtle fade-ins or fully interactive hover animations, the library strikes a perfect balance between power and simplicity. With just a few lines of code, you can elevate your UI and deliver a modern, engaging UX for your users.
Want to create a Nuxt project? Contact us today, and let’s build something great together.