How to add Intercom to a Next.js site

This is how I integrated Intercom into a Next.js website.

Intercom has a guide on how to setup a single page app Integrate Intercom in a single page app but I couldn't find anything specific to React or Next.js.

The guide linked above documents the 3 step process to integrate Intercom into a website:

  1. Copy and paste a code snippet before the tag on every page you want the Messenger to appear
  2. Once your app initialises, add a boot call
  3. Update Intercom whenever the view or URL changes in your app. This will allow people to receive your most recent messages

Great but how do we implement this in Next.js?

1. Add the Intercom snippet to Next.js

We only want Intercom loaded once when the site loads, so we add their snippet to a useEffect hook in _app.tsx.

pages/_app.tsx

function MyApp({ Component, pageProps }: AppProps) {
  ...
  useEffect(() => {

    // Intercom code snippet
    (function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',w.intercomSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Intercom=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/your_app_id';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();

  }, []);
  ...
}

2. Call the Intercom boot method:

Once Intercom is loaded we need to call the boot method. We can do this in the same useEffect hook:

pages/_app.tsx

function MyApp({ Component, pageProps }: AppProps) {
  ...
  useEffect(() => {

    // Intercom code snippet
    (function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',w.intercomSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Intercom=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/your_app_id';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();

    // Call boot method
    (window as any).Intercom('boot', {
      app_id: 'your_app_id'
    });

  }, []);
  ...
}

3. Update Intercom with URL changes

We need to call Intercom on every url change. We can do this with another useEffect in our _app.tsx using the Next.js router event 'routeChangeComplete':

pages/_app.tsx

...
import { useRouter } from 'next/router';
... 

function MyApp({ Component, pageProps }: AppProps) {
  ...
  useEffect(() => {
    const handleRouteChange = () => {
      (window as any).Intercom('update');
    };

    router.events.on('routeChangeComplete', handleRouteChange);

    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, []);
  ...
}

With this code in place we should now have the Intercom message button on the site 😀

intercom-next-js-button.png

Comments (1)

Glenn Rempe's photo

Very helpful. Thanks for the writeup. I did find I had to add a call to:

  const router = useRouter()

Without this the useEffect() for routes will not work.