Skip to content

Latest commit

 

History

History
276 lines (206 loc) · 7.16 KB

File metadata and controls

276 lines (206 loc) · 7.16 KB

gsap-nuxt-module

gsap-nuxt-module

npm version npm downloads License Nuxt

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

  1. Install the module to your Nuxt application with one command:
 npm i gsap-nuxt-module
  1. Add gsap-nuxt-module to the modules section of nuxt.config.ts
export default defineNuxtConfig({
  modules: ['gsap-nuxt-module'],
})
  1. 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

  1. In your nuxt.config.ts, enable the desired GSAP plugins:
export default defineNuxtConfig({
  modules: ["gsap-nuxt-module"],
  gsap: {
    plugins: ["Draggable"],
  },
});
  1. 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())

gsap.context() docs

Contribution

Local development
# 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