gsap-nuxt-module
v1.2.1
Published
GSAP integration for Nuxt.
Readme

gsap-nuxt-module
Enhance your Nuxt application with powerful animations and transitions using GSAP!
Features
- Auto-import GSAP: Easily integrate GSAP without manually importing it in every file.
- Dynamic Plugin Registration: Import and register GSAP plugins only if enabled in
nuxt.config.ts, optimizing performance. - Composable for Each Plugin: Use GSAP plugins as composables for a simple and direct experience.
Quick Setup
- Install the module to your Nuxt application with one command:
npm i gsap-nuxt-module- Add gsap-nuxt-module to the modules section of nuxt.config.ts
export default defineNuxtConfig({
modules: ['gsap-nuxt-module'],
})- Here's how to use GSAP in your component:
<script setup>
const elementRef = ref(null)
onMounted(() => {
gsap.to(elementRef.value, {
x: 100
})
})
</script>
<template>
<div ref="elementRef">GSAP me!</div>
</template>Example Configuration
- In your nuxt.config.ts, enable the desired GSAP plugins:
export default defineNuxtConfig({
modules: ["gsap-nuxt-module"],
gsap: {
plugins: ["Draggable"],
},
});- Here's how to use the Draggable plugin in your component:
<script setup>
const Draggable = useDraggable()
const elementRef = ref(null)
onMounted(() => {
Draggable.create(elementRef.value)
})
</script>
<template>
<div ref="elementRef">Drag me!</div>
</template>You can find more examples in playground
That's it! You can now use gsap-nuxt-module in your Nuxt app ✨
useGsap()
useGsap() returns the GSAP instance directly — use it to access gsap.timeline(),
gsap.to(), gsap.set(), utility methods like gsap.utils.toArray(), and more.
No import needed; it is auto-imported like all other composables.
<script setup lang="ts">
const gsap = useGsap()
const boxRef = ref(null)
onMounted(() => {
const tl = gsap.timeline({ repeat: -1, yoyo: true })
tl.to(boxRef.value, { x: 200, duration: 1, ease: 'power2.inOut' })
.to(boxRef.value, { rotation: 360, duration: 0.8 })
})
</script>Context form (recommended)
Pass a setup function to wrap animations in a gsap.context().
The context reverts automatically when the component unmounts — no onUnmounted boilerplate needed.
During page navigation, cleanup is deferred until after the leave transition finishes.
<script setup lang="ts">
const containerRef = ref<HTMLElement | null>(null)
useGsap(() => {
gsap.from('.box', { opacity: 0, y: 30, duration: 0.6 })
}, { scope: containerRef })
</script>
<template>
<div ref="containerRef">
<div class="box">I animate in safely</div>
</div>
</template>Returns { contextSafe } for wrapping event handlers that add animations after mount.
See the full docs for all options.
Available composables
| Composable | Plugin | nuxt.config.ts key |
|---|---|---|
| useGsap() | GSAP core | — (always available) |
| useScrollTrigger() | ScrollTrigger | ScrollTrigger |
| useScrollSmoother() | ScrollSmoother | ScrollSmoother |
| useSplitText() | SplitText | SplitText |
| useMotionPathHelper() | MotionPathHelper | MotionPathHelper |
| useDraggable() | Draggable | Draggable |
| useFlip() | Flip | Flip |
| useObserver() | Observer | Observer |
| useGSDevTools() | GSDevTools | GSDevTools |
| useCustomEase() | CustomEase | CustomEase |
| useCustomWiggle() | CustomWiggle | CustomWiggle |
| useCustomBounce() | CustomBounce | CustomBounce |
Plugin loading
Only plugins listed in nuxt.config.ts are dynamically imported —
zero bundle overhead for unused plugins.
// nuxt.config.ts
export default defineNuxtConfig({
gsap: {
plugins: ['ScrollTrigger', 'Draggable'],
// only these two will be bundled
},
})Cleanup
When using useGsap() with a setup function, cleanup is automatic. When using the zero-arg form, use onUnmounted to prevent memory leaks.
Plugin registration is handled once by the module at app startup — never call gsap.registerPlugin() manually.
In components, clean up only the instances your component created (tweens, timelines, ScrollTrigger instances, Draggable instances, etc.).
Simple plugin instance cleanup (Draggable):
<script setup lang="ts">
const Draggable = useDraggable()
const boxRef = ref<HTMLElement | null>(null)
let draggables: ReturnType<typeof Draggable.create> = []
onMounted(() => {
if (!boxRef.value) return
draggables = Draggable.create(boxRef.value)
})
onUnmounted(() => {
draggables.forEach((instance) => instance.kill())
draggables = []
})
</script>See real cleanup examples in playground/pages/draggable.vue, playground/pages/scroll-trigger.vue, playground/pages/split-text.vue, and playground/pages/scroll-smoother.vue.
Recommended — gsap.context() (covers all child tweens, timelines and ScrollTriggers):
<script setup lang="ts">
const gsap = useGsap()
let ctx: gsap.Context
onMounted(() => {
ctx = gsap.context(() => {
gsap.to('.box', { x: 100 })
})
})
onUnmounted(() => ctx.revert())
</script>Single timeline:
const gsap = useGsap()
const tl = gsap.timeline()
onUnmounted(() => tl.kill())Contribution
# Install dependencies
npm install
# Generate type stubs
npm run dev:prepare
# Develop with the playground
npm run dev
# Build the playground
npm run dev:build
# Run ESLint
npm run lint
# Run Vitest
npm run test
npm run test:watch
# Release new version
npm run release