For the complete documentation index, see llms.txt. This page is also available as Markdown.

Lottie animations

This guide explains how to add Lottie animations to your custom Crane sections using the same pattern as vape_template/cover-section section template.

Overview

The pattern has three parts:

  1. The animation JSON file — placed in the section's assets/ folder.

  2. The useLottieAnimationLocal composable — handles lazy-loading of both the library and the animation data, and manages the animation lifecycle.

  3. A client/server component split — the actual animation lives in a client-only component; the server counterpart renders an empty placeholder to avoid SSR mismatches.

1. Add dependency

lottie-web must be listed as a direct dependency in your theme's package.json:

"dependencies": {
  "lottie-web": "^5.13.0"
}

2. Place animation file

Put your Lottie JSON file inside the section's assets/ folder:

sections/
  my-section/
    assets/
      my-animation.json   ← here

The animation file can be exported from After Effects (via Bodymovin) or any other Lottie-compatible tool.

3. Add composable file

Create a new file and put it in your project like this: sections/my-section/utils/use-lottie-animation-local.ts:

Notes:

  • Why requestIdleCallback? Loading and decoding a Lottie JSON (which can be 1–2 MB) is expensive. Deferring it to idle time prevents it from competing with the hero image for bandwidth and main-thread time during LCP.

  • Why dynamic import('lottie-web')? The library is only needed on the client and only when the animation is actually shown. Dynamic import keeps it out of the initial JS bundle.

4. Add sectionAssetUrl helper

Similarly, create a new file here: shared/utils/section-asset-url.ts:

Then import and use it in any component that needs to fetch a section asset:

Important: always pass import.meta.url from the calling component file, not from inside a shared helper. Rollup can move shared chunks to a different path, so reading import.meta.url inside the helper would resolve to the wrong location.

5. Add client and server components

Create a new file for the client component in sections/my-section/components/AnimatedBackground.vue:

And a file for the server component in: sections/my-section/components/AnimatedBackgroundServer.vue.

Note: The server component is a no-op placeholder. It must exist to prevent SSR hydration mismatches — the client component must not render on the server.

You also need to import new components in your client/server section files:

Both use <AnimatedBackground :show="showAnimation" /> in the template.

6. Add a CMS toggle (optional)

If you want the end user to be able to enable/disable the animation in the theme editor, add a TOGGLE setting in your section's content file sections/my-section/settings/content.ts:

Then derive a computed prop from it and pass it to the component:

Last updated

Was this helpful?