Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Defining icons from strings in React works, but there is always the 'Could not find icon' error message #525

Open
rmachado-studocu opened this issue Sep 30, 2022 · 4 comments

Comments

@rmachado-studocu
Copy link

This is a direct copy of this bug report by @Stephcraft

Describe the bug
When you do this for example:

<Icon icon={['fas', 'gamepad']}/>

and I even add every icon to the font awesome react library object. I've tried two different ways, same outcome:

import { library  } from "../../node_modules/@fortawesome/fontawesome-svg-core"
import { fas } from '@fortawesome/free-solid-svg-icons'
import { far } from '@fortawesome/free-regular-svg-icons'
import { fab } from '@fortawesome/free-brands-svg-icons'

library.add(fab)
library.add(fas)
library.add(far)
import { library  } from "../../node_modules/@fortawesome/fontawesome-svg-core"
import * as FontAwesomeSolidIcons from '@fortawesome/free-solid-svg-icons'
import * as FontAwesomeRegularIcons from '@fortawesome/free-regular-svg-icons'
import * as FontAwesomeBrandsIcons from '@fortawesome/free-brands-svg-icons'

const geticonList = (module) => Object
    .keys(module)
    .filter(key => key !== "fas" && key !== "far" && key !== "fab" && key !== "prefix" )
    .map(icon => module[icon])

library.add(...[
    ...geticonList(FontAwesomeRegularIcons), 
    ...geticonList(FontAwesomeSolidIcons),
    ...geticonList(FontAwesomeBrandsIcons)
])

The icons do display, but the error message is still present:

Could not find icon { prefix: 'fas', iconName: 'gamepad' }

Reproducible test case

Steps to reproduce:

  1. Access https://codesandbox.io/s/zen-chihiro-ku0do2?file=/pages/index.js
  2. Open the preview in a new tab (or open this URL to go directly: https://ku0do2.sse.codesandbox.io/ )
  3. Open Chrome DevTools, CTRL+SHIFT+P / CMD+SHIFT+P, type "Disable Javascript" and press enter
  4. Refresh the page
  5. You'll notice the 'search' icon doesn't render

Expected behavior
Expected the search icon to render server side and be in the HTML

Desktop (please complete the following information):

  • Browser: Chrome
  • Version: 105

(Although the issue is with SSR, not the browser 😉 )

Additional context

If you change the line

import { config, library } from "@fortawesome/fontawesome-svg-core";

to

const { config, library } = require("@fortawesome/fontawesome-svg-core");

(and restart the server on codesandbox)

you'll notice it start server side rendering....

@robmadole
Copy link
Member

The library is a singleton. So I'm betting that there is something going on with the SSR side of things that results in that singleton being instantiated multiple times.

This will take some investigation into how Next.js works. The workaround for this would be to explicitly reference icons instead of using the Library object.

import { faGamepad } from '@fortawesome/free-solid-svg-icons'

<Icon icon={faGamepad} />

@rmachado-studocu
Copy link
Author

rmachado-studocu commented Oct 4, 2022

The library is a singleton. So I'm betting that there is something going on with the SSR side of things that results in that singleton being instantiated multiple times.

Well, yes... But I'd probably point out that the SSR (NextJS) might be using the ES version and somehow the react-awesome might be using the non-ES version which might lead to inconsistencies at the singleton value...

@kochie
Copy link

kochie commented Oct 31, 2022

FWIW I've been able to solve this in testing bu adding the library to a client side component like below

"use client"

export default function SMButton({ sm }: { sm: SocialMedia }) {
  console.log(sm.icon)
  library.add(faTwitter)
  const icon = findIconDefinition({
    prefix: sm.icon[0],
    iconName: sm.icon[1],
  })
  console.log(icon)
  return (
    <div>
      <Link
        href={sm.link}
        className="text-white transition ease-in-out duration-200"
        onClick={(): void => trackGoal(sm.tracking, 0)}
        onMouseEnter={(event): void => {
          event.currentTarget.style.color = sm.color
          // event.currentTarget.style.transform = 'scale(1.2)'
        }}
        onMouseLeave={(event): void => {
          event.currentTarget.style.color = ''
          // event.currentTarget.style.transform = 'scale(1)'
        }}
      >
        <FontAwesomeIcon
          icon={icon}
          size="1x"
          className="mx-1 transform-gpu transition duration-200 ease-in-out"
        />
      </Link>
    </div>
  )
}

@oniice
Copy link

oniice commented Feb 11, 2023

Also getting this in NextJs on client side components. They work as expected in server side components, but I think it fails in client side as it doesn't see the config.

It is throwing error Could not find icon { prefix: 'far', iconName: 'home' }

I am using the @fortawesome/react-fontawesome to render the icons as recomened in the FA setup.
FA is configured like this in the new layout.tsx file.

import { config, library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/pro-solid-svg-icons';
import { far } from '@fortawesome/pro-regular-svg-icons';
config.autoAddCss = false;
library.add(fas, far, fal);

The using a icon like so <FontAwesomeIcon icon={['far', 'home]} />

I have tried dumping all the imports into a client side component - that fixes it, but then its looking like a lot of bloat from the mulitple imports!

Doing the const { config, library } = require("@fortawesome/fontawesome-svg-core"); hack around does not fix this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants