reactjsnext.jscode-splitting

How to load m bunch of icons dynamically in Next.js?


I do not know if it is worth, but I would load these icons dínamically.

import {
  faCheck,
  faCogs,
  faCoins,
  faCouch,
  faCreditCard,
  faGhost,
  faGift,
  faPuzzlePiece,
  faQrcode,
  faTasks,
  faVideo,
  faChild,
  faCubes,
} from "@fortawesome/free-solid-svg-icons";

I tried load one:

import dynamic from "next/dynamic";
const faCalendar = dynamic(
  async () => (await import("@fortawesome/free-solid-svg-icons")).faCalendar
);

but it raise an error:

Type error: Argument of type '() => Promise<IconDefinition>' is not assignable to parameter of type 'DynamicOptions<{}> | Loader<{}>'.
  Type '() => Promise<IconDefinition>' is not assignable to type '() => LoaderComponent<{}>'.
    Type 'Promise<IconDefinition>' is not assignable to type 'LoaderComponent<{}>'.
      Type 'IconDefinition' is not assignable to type 'ComponentType<{}> | { default: ComponentType<{}>; }'.
        Property 'default' is missing in type 'IconDefinition' but required in type '{ default: ComponentType<{}>; }'.

  20 | import dynamic from "next/dynamic";
  21 | const faCalendar = dynamic(
> 22 |   async () => (await import("@fortawesome/free-solid-svg-icons")).faCalendar
     |   ^
  23 | );
  24 | 
  25 | import { Translation } from "../../tikexModule/Types";

Do you know maybe what is wrong?


Solution

  • You're trying to use the SVG icon definitions from that library as if they were React components, which they're not. next/dynamic only works with components.

    Secondly, it's probably not worth to lazy-load the icon definitions anyway, since import("@fortawesome/free-solid-svg-icons") will need to import the full module for you to extract a single icon from, where import { ... } from ... can do tree-shaking and you'd only include the icon definitions for the icons you actually use.