Vous avez téléchargé une superbe animation Lottie, installé la libraire `react-lottie`, et maintenant votre build Next.js build avec une erreur `document is not defined`. Classique. Le problème ? La bibliothèque `react-lottie` n'est plus maintenue depuis 2020 et ne supporte pas le Server-Side Rendering de Next.js. La solution existe et elle est simple : `lottie-react`.
Installer la bonne libraire : React-Lottie
La première étape consiste à installer la bonne bibliothèque. Oubliez react-lottie, direction lottie-react :
npm install lottie-react
Ensuite, placez vos fichiers JSON d'animation dans le dossier public de votre projet Next.js. Par convention, créez un sous-dossier dédié :
public/
└── animations/
└── loading.json
└── success.json
Si vous travaillez en TypeScript, créez un fichier de types pour vos composants Lottie. Dans votre dossier types (ou src/types), ajoutez :
// types/index.ts
export interface LottieProps {
jsonData: object;
loop?: boolean;
className?: string;
}
Ces types vous permettront d'avoir l'autocomplétion et la validation TypeScript sur vos composants.
La solution : charger l'animation côté client
Voici où la plupart des développeurs se plantent. Si vous utilisez lottie-react directement dans un Server Component Next.js, vous obtiendrez l'erreur redoutée :
ReferenceError: document is not defined
Pourquoi ? Parce que lottie-react dépend de lottie-web, qui tente d'accéder au DOM pendant le rendu côté serveur. Next.js 13+ utilise les Server Components par défaut, et le DOM n'existe pas sur le serveur.
La solution élégante consiste à séparer votre composant Lottie en deux fichiers distincts : un wrapper qui gère le chargement dynamique, et un client component qui fait le rendu réel.
Le pattern en deux fichiers
Créez d'abord le composant client qui utilise lottie-react :
// components/animations/LottieClient.tsx
'use client'
import { LottieProps } from '@/types';
import { useLottie } from 'lottie-react';
const LottieClient = ({
loop = true,
jsonData,
className = "w-full",
}: LottieProps) => {
const defaultOptions = {
animationData: jsonData,
loop: loop,
};
const { View } = useLottie(defaultOptions);
return (
<div className={className}>{View}</div>
);
}
export default LottieClient;
Ce composant est marqué 'use client' en première ligne. Il contient toute la logique liée à Lottie et peut accéder au DOM sans problème.
Ensuite, créez le wrapper qui utilise le dynamic import de Next.js :
// components/animations/LottieAnimation.tsx
'use client'
import { LottieProps } from '@/types';
import dynamic from 'next/dynamic';
import { ComponentType } from 'react';
const LottieWrapper: ComponentType<LottieProps> = dynamic(
() => import('@/components/animations/LottieClient'),
{ ssr: false }
);
const LottieAnimation = (props: LottieProps) => {
return <LottieWrapper {...props} />;
}
export default LottieAnimation;
Le paramètre { ssr: false } est crucial : il indique à Next.js de ne charger ce composant que côté client, après l'hydratation. Pendant le rendu serveur, Next.js ignore complètement ce composant.
Pourquoi ça fonctionne
Ce pattern résout trois problèmes simultanément :
Le SSR : Le dynamic import avec ssr: false empêche l'exécution du code Lottie sur le serveur.
Le tree-shaking : La bibliothèque lottie-react (et son poids de ~82kb minifié) n'est téléchargée que si le composant est réellement utilisé sur la page.
La maintenabilité : Vous importez toujours LottieAnimation, jamais LottieClient directement. Cela garantit que personne dans votre équipe n'utilisera accidentellement le composant sans le wrapper de protection.
Utilisation dans votre app
Maintenant que l'architecture est en place, utiliser vos animations devient un jeu d'enfant. Importez votre composant LottieAnimation et passez-lui le JSON de votre animation.
Import et utilisation basique
// app/page.tsx
import LottieAnimation from '@/components/animations/LottieAnimation';
import loadingAnimation from '@/public/animations/loading.json';
export default function Home() {
return (
<div className="flex items-center justify-center min-h-screen">
<LottieAnimation
jsonData={loadingAnimation}
loop={true}
className="w-64"
/>
</div>
);
}
Le JSON est importé directement comme un objet JavaScript. Next.js gère automatiquement l'import des fichiers .json sans configuration supplémentaire.
Votre composant LottieAnimation accepte trois props essentielles :
jsonData (obligatoire) : L'objet JSON de votre animation. Importez-le depuis votre dossier public/animations/.
loop (optionnel, défaut: true) : Détermine si l'animation doit boucler indéfiniment. Passez false pour une animation qui se joue une seule fois.
className (optionnel, défaut: "w-full") : Classes Tailwind ou CSS pour contrôler la taille et le style du conteneur.
L'utilisation reste simple et prévisible. Vous contrôlez la taille via les classes CSS, le comportement via la prop loop, et l'affichage conditionnel avec les patterns React classiques.
Pro tips
Quelques erreurs courantes et pièges classiques :
Erreur : "Module not found: Can't resolve 'lottie-react'"
Vous avez probablement installé react-lottie au lieu de lottie-react. Désinstallez et réinstallez la bonne version :
npm uninstall react-lottie
npm install lottie-react
Erreur : "document is not defined"
Vous utilisez lottie-react directement sans le wrapper dynamic. Assurez-vous d'importer LottieAnimation et non LottieClient.
L'animation ne s'affiche pas
Vérifiez que votre fichier JSON est bien un export Lottie valide. Testez-le d'abord sur LottieFiles pour confirmer qu'il fonctionne.
L'animation est saccadée
Le JSON est probablement trop lourd. Réduisez le nombre de keyframes ou simplifiez les formes dans After Effects.
Conclusion
Intégrer des animations Lottie dans Next.js n'a rien de compliqué quand on utilise les bons outils. En résumé : installez lottie-react, créez vos deux composants avec le pattern dynamic import, et utilisez-les partout dans votre app sans vous soucier du SSR.
Cette approche fonctionne aussi bien avec Next.js 13, 14 ou 15, et avec l'App Router comme avec le Pages Router. Les animations Lottie apportent une vraie valeur ajoutée à l'expérience utilisateur, et maintenant vous savez comment les implémenter proprement.
À vous de jouer.



