crisp-im / crisp-sdk-web

:package: Include the Crisp chat widget from using frameworks such as React, VueJS, Angular...
https://www.npmjs.com/package/crisp-sdk-web
MIT License
40 stars 13 forks source link

window.$crisp.is is not a function #11

Open RobinChailley opened 1 year ago

RobinChailley commented 1 year ago

I am working on a React application, on which I have installed crisp-sdk-web. Sometimes, randomly, I can't open the chat anymore, and I have the following error message in the console, while sometimes, everything works perfectly. The behavior seems random:

I did call Crisp.configure() with the uuid in my App.tsx.

main.fd36622d.js:2 Uncaught TypeError: window.$crisp.is is not a function
    at e.isChatOpened (main.fd36622d.js:2:1515822)
    at onClick (main.fd36622d.js:2:3023326)
    at onClick (main.fd36622d.js:2:3002732)
    at Object.De (main.fd36622d.js:2:2260503)
    at Be (main.fd36622d.js:2:2260657)
    at main.fd36622d.js:2:2280557
    at Mr (main.fd36622d.js:2:2280651)
    at Lr (main.fd36622d.js:2:2281066)
    at main.fd36622d.js:2:2286508
    at uu (main.fd36622d.js:2:2350177)
    at Re (main.fd36622d.js:2:2259635)
    at Vr (main.fd36622d.js:2:2282360)
    at Gt (main.fd36622d.js:2:2266756)
    at qt (main.fd36622d.js:2:2266540)
    at HTMLDivElement.r (main.fd36622d.js:2:2935323)
baptistejamin commented 1 year ago

Can you please provide all your code?

RobinChailley commented 1 year ago

My App.tsx

...
import { Crisp } from 'crisp-sdk-web';
...

Crisp.configure('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');

const App = () => {
  return (
    ...
  );
}

export default App;

Next, I have a button in a bottom bar. It's when I click on this button, that sometimes, randomly, I get the error message window.$crisp.is not a function

        <BottomNavigationAction
          showLabel
          icon={<ChatIcon className={classes.icon} />}
          label={'Chat'}
          onClick={() => {
            Crisp.chat.isChatOpened() ? Crisp.chat.close() : Crisp.chat.open();
          }}
          style={{
            minWidth: 60,
            padding: 0
          }}
        />
baptistejamin commented 1 year ago

Are you using Next.js?

RobinChailley commented 1 year ago

No i'm not. React only. On the other hand, the issue occurs only when the project is built, but never in dev.

baptistejamin commented 1 year ago

Could it be a linter issue?

Seems you are not using the configure in a lyfecyle hook, so it could be possible the builder tries to evaluate the code, even if it’s not mounted in the dom.

Baptiste Jamin

On 9 Feb 2023, at 10:12, RobinChailley @.***> wrote:

No i'm not. React only. On the other hand, the issue occurs only when the project is built, but never in dev.

— Reply to this email directly, view it on GitHub https://github.com/crisp-im/crisp-sdk-web/issues/11#issuecomment-1423862686, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGTRQ3ZYPIAKPPRFQ2WOULWWSYJFANCNFSM6AAAAAAUWIV3RU. You are receiving this because you commented.

RobinChailley commented 1 year ago

I tried to use the configure function in a life cycle hook, but it does not change anything.

However, I found that the error occurred after browsing via a Link, or whatever, from react-router-dom.

If I browse the app using a "a" with href="..."/, I don't get the error.

If I console.log() into my window.$crisp browser console before I've navigated using react-router-dom, then I get this result:

{push: ƒ, get: ƒ, set: ƒ, is: ƒ, on: ƒ, ...}

which seems to be the expected result, and it works, then "is" is indeed a function. On the other hand, if I console log again, but after navigating with react-router-dom, I have this result there :

[Array(2), Array(2), Array(2), Array(2), Array(2), Array(2)]

And so the error "window.$crisp.is is not a function".

loiclouvet commented 1 year ago

I might have the same issue on a Next.js project. Calling methods only on client side. When I call CrispSdk.chat.isVisible(), it does (very often) trigger following error :

TypeError: window.$crisp.is is not a function
    at e.isVisible

crisp-sdk-web: 1.0.12

SzymonNiemiec commented 1 year ago

@RobinChailley @loiclouvet Have you found a solution?

baptistejamin commented 1 year ago

Hey!

Do you run the latest SDK version?

SzymonNiemiec commented 1 year ago

@baptistejamin 1.0.20, but in my situation Chat is opening on the second try :/

baptistejamin commented 1 year ago

Would it be possible to get more context?

It could be possible you are trying to call Crisp methods way before the window is ready

SzymonNiemiec commented 1 year ago

@baptistejamin In global component (layout.tsx) I configure Crisp.

useEffect(() => {
    Crisp.configure(CRISP_WEBSITE_ID, { safeMode: true })

    if (window.__layout.initialData.user) {
      Crisp.user.setAvatar(window.__layout.initialData.user.avatar)
      Crisp.user.setNickname(window.__layout.initialData.user.username)
      Crisp.session.setData({
        userKey: window.__layout.initialData.user.userKey,
      })

      Crisp.chat.onChatOpened(() => {
        Crisp.session.setData({
          userKey: window.__layout.initialData.user.userKey,
        })
      })
    }
  }, []) 

Then I'm checking if Crisp is injected and I'm rendering HelpButton

{Crisp.isCrispInjected() && <HelpButton key="helpButton" />} 

HelpButton component has handle click function

 const handleAvailableCrispIconClick = () => {
    if (chatOpen && isDesktop) {
      Crisp.chat.close()
      setChatOpen(false)
    } else {
      Crisp.chat.open()
      setChatOpen(true)
    }
  } 

And renders button

 <button
        className="flex h-19 w-19 items-center justify-center rounded-full border border-gold-400 bg-navy-750 shadow-[0_0px_50px_rgba(221,169,73,0.15)] transition-all hover:border-gold-300 hover:shadow-[0_0px_50px_rgba(221,169,73,0.4)]"
        onClick={handleAvailableCrispIconClick}
      >
        {chatOpen && isDesktop ? (
          <motion.div
            key="close"
            initial={{ opacity: 0, rotate: 30, scale: 0.75 }}
            animate={{ opacity: 1, rotate: 0, scale: 1 }}
            exit={{ opacity: 0, rotate: 30, scale: 0.75 }}
            transition={{ duration: 0.3 }}
          >
            <CloseIcon className="h-8 w-8 text-gold-500" />
          </motion.div>
        ) : (
          <motion.div
            key="open"
            initial={{ opacity: 0, scale: 0.75 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.75 }}
            transition={{ duration: 0.3 }}
          >
            <HeadphoneIcon className="h-8 w-8 text-gold-500" />
          </motion.div>
        )}
      </button> 
baptistejamin commented 1 year ago

Hi, our agents are offline at the moment. Please leave a message and we will get back to you as soon as possible.

SzymonNiemiec commented 1 year ago

@baptistejamin any update? :)

baptistejamin commented 1 year ago

Would you be available for a live debug session? You can contact any time at baptiste@crisp.chat

DeepitPatil commented 6 months ago

@SzymonNiemiec @baptistejamin did you figure out what was causing this?

baptistejamin commented 6 months ago

In general such issues are because of server side rendering Sent from my iPhoneOn 9 Apr 2024, at 10:38, Deepit Patil @.***> wrote: @SzymonNiemiec @baptistejamin did you figure out what was causing this?

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: @.***>