@intercom/messenger-js-sdk with React | Community
Skip to main content

We are trying to use official @intercom/messenger-js-sdk with our react app.

https://www.npmjs.com/package/@intercom/messenger-js-sdk

We are calling Intercom instance in our App component

  Intercom({
app_id: ...,
});

and then updating user info when user data is available using following functions:
import { boot, shutdown, update } from "@intercom/messenger-js-sdk";

 

when there is no user data we are calling boot with only id,

boot({
    "app_id": "...",
})

and if there is user data, we are passing required properties to boot function

boot({
    "app_id": "...",
    "user_id": "...",
    "name": "...",
    "email": "...@......",
    "created_at": ....,
})

 

It seems that when calling with boot({ "app_id": "..."}), user data is not cleared and in chat we continue to receive messages as if user is still logged in.

Once boot() is called with user data, can it be rebooted with no data (for example, in scenario if user is logged out from our app and we want new chat instance without user data)?

 

Also, if the boot function is called before Intercom({ id: ... }) finishes initialising, Intercom functions (boot, shutdown, update) cease to work indefinitely and completely. This issue is evidenced by the lack of network calls when inspected, and the shutdown function failing to close the widget.

use case:

import Intercom from "@intercom/messenger-js-sdk";

function App() {
...

Intercom({
app_id: ...,
});

...
// custom hook that utilises Intercom functions
useIntercomInit(userData);
...

 

When using unofficial https://github.com/devrnt/react-use-intercom , everything seems to work without problems. Is there a way to resolve and achieve this with official sdk - @intercom/messenger-js-sdk?

Hi @dev-mo -- Cam from the Intercom Support Engineering team here. 

Looks like you’ve been in touch with one of my teammates, Manuel, via Messenger who’s been able to get you some more details on this 👍

As Manuel mentioned, when using this npm package, you’ll want to use the hardShutdown API method (as described here) to close a logged-in Users session and clear their User data prior to make the “boot({ "app_id": "..."})” call you referenced in your message. 


My team is also using the “@intercom/messenger-js-sdk” package from the docs in a react app.

We are calling the update method when some user data changes, but that is never reflected in intercomSettings or in the user data on the intercom side


My team is also using the “@intercom/messenger-js-sdk” package from the docs in a react app.

We are calling the update method when some user data changes, but that is never reflected in intercomSettings or in the user data on the intercom side

We're experiencing the same issue. When a user transitions from unauthenticated to authenticated, calling update with their new user data doesn't pull in their previous message history. We've found that if we first call update with the user JWT, then call shutdown, and finally boot again with the JWT, their messages do load but the messenger then encounters a connection error. The user is unable to open any existing conversation threads and is redirected back to the start view of the messenger. Is there a better way to handle this?


Hey ​@Samir Fors, Emily here from Support Engineering at Intercom 👋🏼

 

What you’re seeing is a classic session transition issue in SPAs when moving from an anonymous Messenger session to an authenticated one. Calling update() to “switch identities” won’t reliably attach the prior history; you need to end the anonymous session and start a fresh, authenticated session instead. The connection error and bounce back to the start view typically happen when the Messenger still holds the old session cookie or there’s a JWT/user_id mismatch, so it can’t fetch threads for the new identity.

 

Recommended flow (SPA-safe, reliable)

1) Before login — boot as a visitor

Boot without identifiers when nobody is logged in:

window.Intercom('boot', {
app_id: 'YOUR_APP_ID'
});

 

2) When the user initiates login — end the anonymous session

Call shutdown immediately before or as you transition into your auth flow:

window.Intercom('shutdown');

 

3) After successful auth — boot as the authenticated user with JWT

Do not use update() to switch identities; start a fresh boot with the user’s user_id and intercom_user_jwt:

window.Intercom('boot', {
app_id: 'YOUR_APP_ID',
user_id: '<USER_ID>',
email: '<OPTIONAL_EMAIL>',
name: '<OPTIONAL_NAME>',
intercom_user_jwt: '<SIGNED_JWT>'
});

This will load their existing conversations and also merge any anonymous activity from the same device into their account.

 

4) During session — use update() for changes and SPA route pings

Use update() for attribute changes or to ping Intercom on route changes (throttle to avoid the 20-per-page limit):

window.Intercom('update', { last_request_at: Math.floor(Date.now()/1000) });

 

5) On logout — end the session

Always shut down to clear the cookie so the next person on the device won’t see the prior user’s data:

window.Intercom('shutdown');

 

The robust, supported approach is: shutdown the anonymous session, then boot once as the authenticated user with a valid JWT; don’t try to switch identities via update(). This will reliably load historical conversations and prevent the connection errors you’re seeing.


Hello Emily, 

Thank you for your response. However, following your suggestions, I’m still seeing the same result, which is quite frustrating. 

After moving from an anonymous session to an authenticated one, users can never open their old conversations unless they reload the page after auth.

 

What I’m doing (React SPA, @intercom/messenger-js-sdk)

  • On app load:
    • IntercomSDK({ app_id })
  • On login success (SPA transition), I gate until:
    • SDK initialized
    • User profile loaded (app-side)
  • Then I do:
    // Upon loading the component
    useEffect(() => {
    IntercomSDK({
    app_id,
    });
    }, []);


    // Later when the user is authenticated
    useEffect(() => {
    const { token } = await get<{ token: string }>({
    endpoint: 'some-endpoint',
    });

    // end anonymous session
    await shutdown(); 
    // tried multiple values
    await delay(300–700); 

    boot({
       app_id,
       user_id: user.id,            
       intercom_user_jwt: token,  
       session_duration: 86400
    });

    setTimeout(() => update({ last_request_at: Math.floor(Date.now()/1000) }), 300);


    }, [isAuthenticated]);

     

What I’ve tried

  • Avoided identity switching via update(), only shutdown, then boot once with JWT.
  • Ensured user_id strictly equals JWT subject; also tried omitting email on boot.
  • Prevented any other update() during the swap; hid the launcher during transition and re-enabled after a short delay.
  • Added waits after shutdown and after boot (300–700ms); also tried initial visitor boot while unauthenticated vs. not.
  • JWT is minted fresh at login, correct workspace/app, not expired.

Observed behavior

  • After login (without page reload), existing conversations are listed but cannot be opened. Creating a new message can also fail.
  • If I reload the page (so the user starts authenticated), everything works: old messages open and new messages send successfully.
  • Network sometimes shows 403 Forbidden “App suspended” when attempting to open a thread:
    • POST /messenger/web/conversations/:id → 403 with message “App suspended”

What can I do to make this work as expected?