How to add Facebook chat messenger to Next.js?
Asked Answered
I

5

5

I am trying to add Facebook customer chat in my Next.js app, but it doesn't work. I couldn't find any problem with my code.

  1. How can I add Facebook customer chat in my Next.js app?
  2. Is there any mistake in my code?
  3. Any better implementation to solve this problem?

Here is my code.

_document.js

import Document, { Html, Head, Main, NextScript } from "next/document";
import React from "react";
import { getLangParam } from "../utils";

export default class MyDocument extends Document {
  render() {
    return (
      <Html >
        <Head />
          <noscript
            dangerouslySetInnerHTML={{
              __html: `<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-MPQD53D"
                        height="0" width="0" style="display:none;visibility:hidden"></iframe>`,
            }}
        <body>
          <Main />
          <NextScript />
        </body>
          <div id="fb-root"></div>
          <script
          dangerouslySetInnerHTML={{
            __html: `
            window.fbAsyncInit = function() {
              FB.init({
                xfbml            : true,
                version          : 'v10.0'
              });
            };
            (function(d, s, id) {
              var js, fjs = d.getElementsByTagName(s)[0];
              if (d.getElementById(id)) return;
              js = d.createElement(s); js.id = id;
              js.src = 'https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js';
              fjs.parentNode.insertBefore(js, fjs);
            }(document, 'script', 'facebook-jssdk'));
            `,
          }}
        />
        <div className="fb-customerchat"
          attribution="biz_inbox"
          page_id="1043670075778655">
        </div>
      </Html>
    );
  }
}
Isaac answered 21/7, 2021 at 3:13 Comment(1)
It's resolved in comment Quan TranCombust
L
7

My solution:

import Script from 'next/script';

function Facebook() {
  return (
    <div>
      <div id="fb-root"></div>

      <div id="fb-customer-chat" className="fb-customerchat"></div>
      <Script strategy="lazyOnload">
        {`
            var chatbox = document.getElementById('fb-customer-chat');
            chatbox.setAttribute("page_id", "YOUR_PAGE_ID");
            chatbox.setAttribute("attribution", "biz_inbox");
      
            window.fbAsyncInit = function() {
              FB.init({
                xfbml            : true,
                version          : 'v12.0'
              });
            };
      
            (function(d, s, id) {
              var js, fjs = d.getElementsByTagName(s)[0];
              if (d.getElementById(id)) return;
              js = d.createElement(s); js.id = id;
              js.src = 'https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js';
              fjs.parentNode.insertBefore(js, fjs);
            }(document, 'script', 'facebook-jssdk'));
        `}
      </Script>
    </div>
  );
}

export default Facebook;
Lithe answered 2/10, 2021 at 8:34 Comment(5)
it works, require next version ^11.0.0Godden
It works for me. Next.js version is 11.1.2Combust
This solution slows down the website, do you have any idea to avoid it? #73763103Garrote
Are you sure? You are not using that same code as my example, please read carefully again!Lithe
@QuanTran, I adjusted based on your code, have <Script strategy="lazyOnload"> now. But still it says Some third-party resources can be lazy loaded with a facade 1 facade alternative available Does <div id="fb-root"></div> needed in your solution? resourse: …sdk/xfbml.customerchat.jsGarrote
S
2

My solution

Embed FB Chat Plugin into React (esp Next.js) need few tweaks.

  • Embed by FB's instructions, but add a cleanup (remove FB , window.FB) to make it works when navigating to another page.

  • Remember to whitelist your domain (FB Chat require https) in the FB Chat plugin configuration page.

Use the Facebook1 component below:

import { useEffect } from "react";

/**
 *
 */
export function init() {
  var chatbox = document.getElementById("fb-customer-chat");
  chatbox.setAttribute("page_id", "your_page_id"); // TODO: move to args
  chatbox.setAttribute("attribution", "biz_inbox");

  window.fbAsyncInit = function () {
    FB.init({
      xfbml: true,
      version: "v11.0",
    });
  };

  (function (d, s, id) {
    var js,
      fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s);
    js.id = id;
    js.src = "https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js";
    fjs.parentNode.insertBefore(js, fjs);
  })(document, "script", "facebook-jssdk");
}

/**
 *
 */
export function cleanup() {
  (function (d, id) {
    var target = d.getElementById(id);
    if (target) {
      target.parentNode.removeChild(target);
    }
  })(document, "facebook-jssdk");

  delete window.FB;
}

export function Facebook1() {
  useEffect(() => {
    console.log("Facebook1");
    init();

    return () => {
      cleanup();
    };
  }, []);

  return (
    <div>
      <div id="fb-root"></div>

      <div id="fb-customer-chat" className="fb-customerchat"></div>
    </div>
  );
}

You can check my full examples at https://github.com/nghiaht/examples/tree/develop/with-fb, thanks for encouraging me to write down because sometimes I meet him in projects.

My final notes

Try to put features into components (Facebook1...) and import them in needed places. Putting in _document.js would those things appear globally in your app (it hurts :D).

Sacculate answered 21/7, 2021 at 9:31 Comment(1)
Do you get issues with hydration failing due to the initial UI being different than was what rendered on the server? I'm getting that now.Aloha
E
1

Good question. I was looking for a solution and found one that seems to work for me. I used dangerouslySetInnerHTML in a script tag. I put the script tag in the body underneath the div element that FB provides inside the body tag. When I put the script tag higher in the __documents.js page it didn't load the messenger. It looked something like this.

           <body>
          
                <div id="fb-root"></div>

               <div id="fb-customer-chat" className="fb-customerchat"></div>


              <script dangerouslySetInnerHTML = {{
                        __html : 

                        `
                        var chatbox = document.getElementById('fb-customer-chat');
                        chatbox.setAttribute("page_id", “22xxxx”xx);
                        chatbox.setAttribute("attribution", "biz_inbox");
                  
                        window.fbAsyncInit = function() {
                          FB.init({
                            xfbml            : true,
                            version          : 'v12.0'
                          });
                        };……

I believe that there are ways to detect which page you are on so that the messenger doesn't show up on all pages. something like var path = this.props.dangerousAsPath;

I put the script outside of the <Head/> tag

Expedient answered 19/9, 2021 at 13:44 Comment(0)
K
1

use it in your layout component

import MessengerCustomerChat from 'react-messenger-customer-chat'
const DefaultLayout = ({ childrens }) => {
    return (
     <> 
     {childres}
     <MessengerCustomerChat
          pageId={"Your Page Id if any"}
          appId={process.env.NEXT_PUBLIC_FACEBOOK_APP_ID}
          version={"version of your app like 12.0"}          
          xfbml={true}
        />
    </>

    )}

That's it.

resource :

https://www.npmjs.com/package/react-messenger-customer-chat

Klement answered 13/1, 2022 at 6:20 Comment(0)
S
0

I realized that I inserted my script in _document.tsx and it should be in _app.tsx.. Also it should be outside Head component. (Next 11 and adding Script tags not working. No scripts are rendered) What worked for me was..

I created a utility like this..

import Script from "next/script";

const FacebookMessenger = () => {
return (
<div>
  <div id="fb-root"></div>
  <div id="fb-customer-chat" className="fb-customerchat"></div>
  {/* eslint-disable-next-line @next/next/inline-script-id */}
  <Script strategy="lazyOnload">
    {`
      var chatbox = document.getElementById('fb-customer-chat');
      chatbox.setAttribute("page_id", "xxREPLACEMEWITHREALDATAxxxx");
      chatbox.setAttribute("attribution", "biz_inbox");

      window.fbAsyncInit = function() {
        FB.init({
          xfbml            : true,
          version          : 'v15.0'
        });
      };

      (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) return;
        js = d.createElement(s); js.id = id;
        js.src = 'https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js';
        fjs.parentNode.insertBefore(js, fjs);
      }(document, 'script', 'facebook-jssdk'));
    `}
  </Script>
</div>
 );
};

export default FacebookMessenger;

then inserted it in _app.tsx.. OUTSIDE "next/head" like this...

_app.tsx
import Head from "next/head";
import FacebookMessenger from "utils/FacebookMessenger";


const App = ({ Component, pageProps }: MyAppProps) => {
return (
<Fragment>
  <FacebookMessenger /> // < ------ Outside Head 
  <Head>
    <title>PC Worth - We make IT worth</title>
    <meta
      name="description"
      content="Fastest-growing computer parts business. Wide selection of high-quality components at competitive prices. Shop now and see the difference."
    />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta httpEquiv="Content-Type" content="text/html; charset=utf-8" />

    <link rel="canonical" href="https://pcworth.com/" />
    <GoogleAnalytics />
  </Head>

  <Main />
  <Analytics />
</Fragment>
 );
 };

export default App;
Suggestible answered 4/3, 2023 at 7:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.