Reputation: 59
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.
Here is my code.
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>
);
}
}
Upvotes: 5
Views: 9977
Reputation: 16
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;
Upvotes: 0
Reputation: 21
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
Upvotes: 1
Reputation: 186
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;
Upvotes: 7
Reputation: 5195
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
Upvotes: 1
Reputation: 795
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.
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).
Upvotes: 2