Integration of FreshChat with React Web

Hi all,

I am trying to integrate the FC widget into a React web application. Does anyone have experience doing this and can point me towards some good resources.

I have it almost working, but I am having problem clearing a user on logout, then setting a different user on login, without closing the browser window first.

It appears that the widget does not like being initiated with one user and their restoreId then switching to a different user. Any advice on dealing with this scenario?

Many thanks in anticipation
Paul

2 Likes

Facing the same issue

Did you get any clue? Facing same issue

I’m also facing the same issue while integrating freshchat with React web application. Any workaround to fix this?
Thanks in advance

React_app.zip (344.1 KB)

I have added react sample app which contain restoreid logics, you can check this.
@KiwiPaul @Jinus_MK

  1. Download the zip
  2. Extract the zip folder
  3. npm install
  4. npm start
1 Like

Hey @Mani_Tamilarasan ,

I wanted to express my gratitude for your assistance. Your guidance helped me in implementing the chat widget on my React web application with the restore ID concept. However, I’ve encountered some challenges regarding restoring chats or displaying previous conversations once a chat is resolved. After each chat resolution, whether by bot or agent, the system prompts for CSAT and then initiates a completely new chat session. Our aim is to provide users with access to their previous chat history upon login.

Additionally, there are a few differences in our implementations:

  • All users are pre-created in our database, and we retrieve the restore ID from the backend upon user login. Consequently, we only display the widget after users log in.
  • We utilize a custom button to toggle the widget open and closed.

Your continued support in resolving these issues would be greatly appreciated. Thanks

Oh cool, thanks, @Jinus_MK . I am happy to assist you.

I need a couple of information needed to solve your issues.
Firstly, will the widget be displayed both after login and before login?
In these cases, the above mentioned react zip code will help to solve the issues

No need to show login page only show the widget after login, means there are few code changes in the above script.

As you mentioned, upon clicking the toggle the button only you will show the widget rite, In the case when you logout the page will u destroy the widget or hide the widget?

Hey @Mani_Tamilarasan ,

We are displaying the widget only after login (which means I’m initializing the widget only after successful login )

 useEffect(() => {
    if (loggedIn && restoreId && userId) {
      widgetService.initializeFreshChatWidget({
        restoreId,
        externalId: userId,
        onUnreadCountChange: handleUnreadCountChange,
      });
    }
  }, [loggedIn, restoreId, userId, handleUnreadCountChange]);

Also, when the user logs out I’m calling the window.fcWidget.user.clear(); function and then it will automatically destory the widget as you’ve already added a listener in the provided snippet and it works as expected.

The only issue I’m facing right now is , I’m unable to restore the chat after resolving even though the chats are restored as expected till the conversation getting resolved but this is against our expectation since we would like to show the chat history always

Please let me know if you need any more information

There is an option called Hide Resolve Conversation in admin settings, if you enable that option, it will remove the chat history once you resolve the conversations.

1 Like

Thank you so much for the help @Mani_Tamilarasan . I’ve missed to toggle this setting and it’s working as expected right now.

Hey @Mani_Tamilarasan ,
We have observed that the in-app freshchat notifications when new messages are received, disrupting the overall user experience of our application.
The users can easily identify if there are any unread messages from Freshchat through the unread message count indicator. Therefore, we would like to explore the possibility of disabling the in-app notifications.
Thank you for your attention to this request. I look forward to your response and assistance.


@Mani_Tamilarasan

Also, I would like to bring your attention to one more issue I’m facing while integrating freshchat with our React web application.

we encountered the following error on our console upon initializing the widget successfully.

TypeError: Cannot read properties of undefined (reading 'alias') at n.trigger (fd-messaging.ccd65bd…4158ef4.js:1:192947)

Could you please provide assistance in troubleshooting this error and guiding us on the correct steps to resolve it? Any insights or recommendations you could offer would be greatly appreciated.


Thanks in advance

I will take your concern to the business team, and I will update the same.

1 Like

In Which use case are you getting this error, Can u share your snippet that when u got error.

I’m getting the above error as soon as I initialize the chat after the user is logged in.

import { updateFCUnreadMessageCount } from 'actions/help-and-support';
import { useAppDispatch, useAppSelector } from 'hooks';
import useTeacherDetails from 'hooks/user/useTeacherDetails';
import widgetService from 'modules/freshchat/widget-service';
import { useEffect, useCallback } from 'react';

import { useIsFreshchatEnabled } from './use-is-freshchat-enabled';

const useFreshchat = () => {
  const { loggedIn = false, userId } = useAppSelector(store => store.auth);
  const { freshchat_user: freshchatUser } = useTeacherDetails() ?? {};
  const dispatch = useAppDispatch();
  const isFreshchatEnabled = useIsFreshchatEnabled();
  const { restore_id: restoreId } = freshchatUser ?? {};

  const handleUnreadCountChange = useCallback(
    (resp: { count: number } | null | undefined) => {
      const { count = 0 } = resp ?? {};

      dispatch(updateFCUnreadMessageCount(count));
    },
    [dispatch],
  );

  useEffect(() => {
    if (loggedIn && restoreId && userId && isFreshchatEnabled) {
      widgetService.initializeFreshChatWidget({
        restoreId,
        externalId: userId,
        onUnreadCountChange: handleUnreadCountChange,
      });
    }
  }, [loggedIn, restoreId, userId, handleUnreadCountChange, isFreshchatEnabled]);

  useEffect(() => {
    window.addEventListener('popstate', widgetService.closeWidget);

    return () => {
      window.removeEventListener('popstate', widgetService.closeWidget);
    };
  }, []);
};

export default useFreshchat;

import { FRESHCHAT_WIDGET_URL, LEAP_TEACHER_FRESHCHAT_TOPIC } from 'constants/api';

type UnreadCountChangeCallback = (resp: { count: number }) => void;
interface InitializeFreshChatWidgetParams {
  externalId: string;
  restoreId: string;
  onUnreadCountChange: UnreadCountChangeCallback;
}
interface MessengerConfig {
  externalId: string;
  restoreId: string;
}

class WidgetService {
  externalId: string | null = null;
  restoreId: string | null = null;
  handleUnreadCountChange: UnreadCountChangeCallback = () => null;

  freshChatEvents = () => {
    window.fcWidget.on('user:cleared', () => {
      window.fcWidget.destroy();
    });

    window.fcWidget.on('unreadCount:notify', (resp: { count: number }) => {
      this.handleUnreadCountChange(resp);
    });

    window.fcWidget.on('widget:destroyed', () => {
      const scriptToRemove = document.getElementById('freshchatScript');
      const head = document.head || document.getElementsByTagName('head')[0];

      if (scriptToRemove) {
        head.removeChild(scriptToRemove);
      }

      this.externalId = null;
      this.restoreId = null;
    });
  };

  initWidget = (messengerConfig: MessengerConfig) => {
    window.fcWidgetMessengerConfig = {
      tags: [LEAP_TEACHER_FRESHCHAT_TOPIC],
      config: {
        eagerLoad: true,
        headerProperty: {
          hideChatButton: true,
        },
      },
      ...messengerConfig,
    };
    const freshchatScript = document.createElement('script');

    freshchatScript.src = FRESHCHAT_WIDGET_URL;
    freshchatScript.setAttribute('chat', 'true');
    freshchatScript.id = 'freshchatScript';
    freshchatScript.onload = () => {
      window.fwcrm.on('widget:loaded', this.freshChatEvents);
    };
    const head = document.head || document.getElementsByTagName('head')[0];

    head.insertBefore(freshchatScript, head.firstChild);
  };

  initializeFreshChatWidget = ({
    externalId,
    restoreId,
    onUnreadCountChange,
  }: InitializeFreshChatWidgetParams) => {
    this.externalId = externalId;
    this.restoreId = restoreId;
    this.handleUnreadCountChange = onUnreadCountChange;

    if (window.fcWidget && window.fcWidget.isInitialized() === true) {
      window.fcWidget.user.isExists().then(
        (data: { data: any; success: boolean }) => {
          if (data.data && data.success) {
            window.fcWidget.user.clear();
          } else {
            window.fcWidget.destroy();
          }
        },
        () => null,
      );
    } else {
      this.initWidget({
        externalId,
        restoreId,
      });
    }
  };

  clearUser = () => {
    if (window.fcWidget) {
      window.fcWidget.user.clear();
    }
  };

  isWidgetLoaded = () => {
    return !!window.fcWidget && window.fcWidget.isLoaded();
  };

  isWidgetOpen = () => {
    return !!window.fcWidget && window.fcWidget?.isOpen();
  };

  openWidget = () => {
    if (window.fcWidget) {
      window.fcWidget.open();
    }
  };

  closeWidget = () => {
    if (window.fcWidget && this.isWidgetOpen()) {
      window.fcWidget.close();
    }
  };
}

const widgetServiceInstance = new WidgetService();

export default widgetServiceInstance;

Thanks for the help, I have already tried communicating with the support team but no luck with receiving proper solution


Can u confirm how many times this useEffect is triggering ?

 widgetService.initializeFreshChatWidget({

Ideally this should call only once at a time after logged in.

Hey yes, this is called only once after logged in… just confirmed with logs!
@Mani_Tamilarasan

can u pls share FRESHCHAT_WIDGET_URL and LEAP_TEACHER_FRESHCHAT_TOPIC i will check with the script and confirm it.