Integration
data-anim works with any HTML-based project. Since it uses HTML attributes and injects its own CSS, there’s nothing framework-specific to configure.
Table of Contents
Static HTML
The simplest integration. Add the script tag and start using attributes.
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/data-anim@latest/dist/data-anim.js"></script>
</head>
<body>
<h1 data-anim="fadeInUp">Hello World</h1>
<p data-anim="fadeInUp" data-anim-delay="200ms">
Welcome to my site.
</p>
</body>
</html> React (Vite)
Install via npm:
npm install data-anim Import once at the top of your entry file. data-anim auto-initializes and uses MutationObserver to detect components as they mount.
// src/main.jsx
import 'data-anim';
import { createRoot } from 'react-dom/client';
import App from './App';
createRoot(document.getElementById('root')).render(<App />); Then use data-anim attributes in any component:
function Features() {
return (
<section data-anim-stagger="100">
<h2 data-anim="fadeInUp">Features</h2>
<div data-anim="fadeInUp">Fast</div>
<div data-anim="fadeInUp">Lightweight</div>
<div data-anim="fadeInUp">Zero config</div>
</section>
);
} No useEffect, no refs, no wrapper components needed.
Vue (Vite)
Install via npm:
npm install data-anim Import once at the top of your entry file. data-anim auto-initializes and uses MutationObserver to detect components as they mount.
// src/main.js
import 'data-anim';
import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app'); Then use data-anim attributes in any component:
<template>
<section data-anim-stagger="100">
<h2 data-anim="fadeInUp">Features</h2>
<div data-anim="fadeInUp">Fast</div>
<div data-anim="fadeInUp">Lightweight</div>
<div data-anim="fadeInUp">Zero config</div>
</section>
</template> No onMounted, no refs, no directives needed.
Next.js
Install via npm:
npm install data-anim Import in your root layout. Use next/script with strategy="beforeInteractive" for anti-FOUC protection, or use the npm import approach in a Client Component:
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<Script
src="https://unpkg.com/data-anim@latest/dist/data-anim.js"
strategy="beforeInteractive"
/>
</head>
<body>{children}</body>
</html>
);
} Alternatively, import the npm package via a Client Component. Note: data-anim accesses document at module level, so use a dynamic import inside useEffect to avoid SSR errors:
// app/DataAnim.tsx
'use client';
import { useEffect } from 'react';
export default function DataAnim() {
useEffect(() => {
import('data-anim');
}, []);
return null;
} // app/layout.tsx
import DataAnim from './DataAnim';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<DataAnim />
{children}
</body>
</html>
);
} Then use attributes in any Server or Client Component:
// app/page.tsx
export default function Home() {
return (
<main>
<h1 data-anim="fadeInUp">Welcome</h1>
<p data-anim="fadeInUp" data-anim-delay="200">
Built with Next.js + data-anim
</p>
</main>
);
} Nuxt
Use useHead in your root component to load data-anim via CDN. This ensures the script is included in the SSR output for anti-FOUC protection:
<!-- app/app.vue -->
<script setup>
useHead({
script: [
{
src: 'https://unpkg.com/data-anim@latest/dist/data-anim.js',
tagPosition: 'head',
},
],
});
</script>
<template>
<div>
<h1 data-anim="fadeInUp">Welcome</h1>
<p data-anim="fadeInUp" data-anim-delay="200">
Built with Nuxt + data-anim
</p>
</div>
</template> No extra plugins or nuxt.config.ts changes needed.
Astro
Add to your base layout:
---
// src/layouts/Layout.astro
---
<html>
<head>
<script src="https://unpkg.com/data-anim@latest/dist/data-anim.js"></script>
</head>
<body>
<slot />
</body>
</html> Use in any .astro or .mdx page:
<section data-anim-stagger="100ms">
<h1 data-anim="fadeInUp">Welcome</h1>
<p data-anim="fadeInUp">Built with Astro + data-anim</p>
</section> Hugo
Add the script to your base template’s <head>:
<!-- layouts/_default/baseof.html -->
<!DOCTYPE html>
<html>
<head>
{{ partial "head.html" . }}
<script src="https://unpkg.com/data-anim@latest/dist/data-anim.js"></script>
</head>
<body>
{{ block "main" . }}{{ end }}
</body>
</html> Use in your Markdown with raw HTML:
<!-- content/posts/my-post.md -->
<div data-anim="fadeInUp">
## My Animated Section
This content will fade in when scrolled into view.
</div> WordPress
Add the script to your theme’s header.php or use a plugin to inject it in the <head>.
// functions.php
function enqueue_data_anim() {
wp_enqueue_script(
'data-anim',
'https://unpkg.com/data-anim@latest/dist/data-anim.js',
array(),
null,
false // Load in <head>, not footer
);
}
add_action('wp_enqueue_scripts', 'enqueue_data_anim'); Then use attributes in your templates or the block editor (Custom HTML block):
<div data-anim="fadeInUp" class="wp-block-group">
<h2>Section Title</h2>
<p>Section content goes here.</p>
</div> HTMX
data-anim works seamlessly with HTMX’s dynamic content swapping. After HTMX swaps content, data-anim’s MutationObserver automatically picks up new [data-anim] elements.
<div hx-get="/api/content" hx-trigger="click" hx-swap="innerHTML">
<button>Load More</button>
</div>
<!-- Server returns: -->
<div data-anim="fadeInUp">
New content animates automatically!
</div> No extra configuration needed. data-anim watches the DOM for changes.
Turbo (Hotwire)
Similar to HTMX, Turbo replaces page content dynamically. data-anim re-initializes automatically on turbo:load.
<!-- Just include data-anim in your layout head -->
<head>
<script src="https://unpkg.com/data-anim@latest/dist/data-anim.js"></script>
</head>
<!-- Use normally in any Turbo-driven page -->
<div data-anim="fadeInUp">
This works across Turbo page transitions
</div> Key Principle
data-anim is framework-agnostic by design. It works anywhere you can write HTML attributes. The only requirement is loading the script in the <head> (synchronously) for anti-FOUC protection.