Vue / Nuxt

Initialize once in your root component's mount lifecycle:

vue
<!-- App.vue -->
<script setup>
import { onMounted, onUnmounted } from 'vue'
import Vivace from 'vivace-css'
import 'vivace-css/vivace.css'

onMounted(() => Vivace.init())
onUnmounted(() => Vivace.destroy())
</script>

<template>
  <RouterView />
</template>

Annotate templates directly — plain attributes, no directive needed:

vue
<h1 data-viv="@fd @sl-y_ease-out-expo">Hello</h1>

<ul data-viv="@fd_child-ascend" data-viv-on="appearing">
  <li v-for="item in items" :key="item.id">{{ item.label }}</li>
</ul>

Nuxt

Register it as a client-only plugin so it never touches the server render:

ts
// plugins/vivace.client.ts
import Vivace from 'vivace-css'
import 'vivace-css/vivace.css'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('app:mounted', () => Vivace.init())
})

v-if, v-for and route changes

Vue mounting new DOM is picked up by the engine's MutationObserver — elements rendered by v-if, list insertions and page navigations register themselves. Nothing to call in individual components.

Programmatic control

vue
<script setup>
import { useTemplateRef } from 'vue'
import Vivace from 'vivace-css'

const box = useTemplateRef('box')
</script>

<template>
  <div ref="box" data-viv="@pop">…</div>
  <button @click="box && Vivace.trigger(box)">replay</button>
</template>
Portrait of Axel RAKOTOARIVAO
Created by
Axel RAKOTOARIVAO
MIT — keyframe DSL inspired by A.css
bun add vivace-css