Svelte / SvelteKit
Initialize once in your root layout inside an $effect — it only runs in the
browser, and the cleanup handles hot reloads and teardown. This site is built exactly this way.
svelte
<!-- src/routes/+layout.svelte -->
<script>
import Vivace from 'vivace-css'
import 'vivace-css/vivace.css'
let { children } = $props()
$effect(() => {
Vivace.init()
return () => Vivace.destroy()
})
</script>
{@render children()}Then annotate any element, in any component:
svelte
<h1 data-viv="@fd @sl-y_ease-out-expo">Hello</h1>
<ul data-viv="@fd_child-ascend" data-viv-on="appearing">
{#each items as item}
<li>{item}</li>
{/each}
</ul>Route changes & dynamic content
Client-side navigation mounts new DOM — the MutationObserver registers it automatically, so data-viv-on="load" elements animate on every page you navigate to, and appearing elements arm themselves. No per-page code.
SSR
The module is SSR-safe: importing it on the server is a no-op (every API call guards on document). Import the CSS in the layout so server-rendered pages ship the styles
with the first paint.
Programmatic control
svelte
<script>
import Vivace from 'vivace-css'
let box
</script>
<div bind:this={box} data-viv="@pop">…</div>
<button onclick={() => Vivace.trigger(box)}>replay</button>