'How to import Lottie component?

Remix is prone to the following error when using import on top-level components TypeError: Cannot read properties of undefined (reading 'root').

So I've done as they recommend and have the following imports.server.tsx file.

export * from "lottie-react";

Then my component app.tsx looks exactly like this lottie example.

import React from "react";
import * as Lottie from "../imports.server";
import groovyWalkAnimation from "../../public/assets/102875-cinema-clap.json";

export default function App() {
  return (
    <>
      <h1>lottie-react - Component</h1>
      <Lottie animationData={groovyWalkAnimation} />;
    </>
  );
}

but I get the following error

JSX element type 'Lottie' does not have any construct or call signatures.ts(2604)

Edit 1:

The following seems to have worked for imports:

imports.server.tsx



import Lottie from "lottie-react";
export default Lottie;



AppTry.tsx



import React from "react";
import Lottie from "../imports.server";

import groovyWalkAnimation from "../../public/assets/102875-cinema-clap.json";

export default function AppTry() {
  // console.log(LottieModule);
  return (
    <>
      <h1>lottie-react - Component</h1>
      <Lottie animationData={groovyWalkAnimation}></Lottie>
    </>
  );
}

Now the various paramaters like "animationData" and "autoPlay" pop up on the Lottie component which I assume means the import is working? However I am now getting this error when rendering AppTry.tsx?

react.development.js:220 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of AppTry.

Edit 2:

import { useLottie } from "lottie-react";
import Lottie from "lottie-react";
import groovyWalkAnimation from "../../public/assets/102875-cinema-clap.json";

const Example = () => {
  const options = {
    animationData: groovyWalkAnimation,
    loop: true,
    autoplay: true,
  };

  const { View } = useLottie(options);

  return View;
};

const Example1 = () => {
  return <Lottie animationData={groovyWalkAnimation} />;
};

export const TopicOverview = () => {

  return (
    <div className="space-y-20">
      <Example1></Example1>
      <Example></Example>
    </div>
  );
};


Solution 1:[1]

Looks like it has to do with your way of importing Lottie.

Shouldn't you import Lottie like this?:

import Lottie from "lottie-react";

Solution 2:[2]

I also struggled to get this working in Remix. You can do the lazy load import somewhere higher up in the tree too.

import type { LottiePlayer } from "@lottiefiles/lottie-player";
import { useEffect } from "react";

interface LottieCompProps {
  src: LottiePlayer["src"];
  style?: Partial<LottiePlayer["style"]>;
}

function LottieComp({ src, style = {} }: LottieCompProps): JSX.Element | null {
  // NB: otherwise, will cause app to crash. see https://remix.run/docs/en/v1/guides/constraints#third-party-module-side-effects
    useEffect(() => {
      import("@lottiefiles/lottie-player");
    },[]);

  if (typeof document === "undefined") return null;
  return (
    //@ts-expect-error dynamic import
    <lottie-player
      autoplay
      loop
      mode="normal"
      src={typeof src === "string" ? src : JSON.stringify(src)}
      style={{
        ...{
          width: "100%",
          backgroundColor: "transparent",
        },
        ...style,
      }}
    />
  );
}

export default LottieComp;

Solution 3:[3]

The issue was in my root.tsx, an ErrorBoundary() function that called an <UnexpectedErrors/> component. This same component was being called in various slug.tsx files. For some reason remix did not like this.

Having two different <UnexpectedErrors/> and <UnexpectedErrors2/> components - one for the slug.tsx files and one for the index.tsx files fixed this.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Gobli
Solution 2 mattf96
Solution 3 rowen