change facebook sdk lang code dynamically in vue (nuxt) - facebook

i am currently working on a simple like implementation in nuxt. when i change the language with 1i8n, i want to change the facebook sdk language accordingly, so the button renders in the given language code when i change the overall app language. my code looks like this:
import config from '#/config'
export default {
data() {
return {
FB_APP_ID: config.appname.FB_APP_ID
}
},
mounted() {
var langua;
if (this.$i18n.locale == 'en') {
langua = "en_US";
}
if (this.$i18n.locale == 'de') {
langua = "de_DE";
}
window.fbAsyncInit = () => {
FB.init({
appId: this.FB_APP_ID,
cookie: true,
xfbml: true,
version: 'v2.8'
})
}
(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 = "//connect.facebook.net/" + langua + "/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
}
it works but the dynamic change is not happening, do i miss something like async on the button sdk here ??? no idea, i am new to vue, help is appreciated thanks a lot.

That won’t work, the SDK can only be embedded and initialized once.
This is not entirely true: there is a workaround.
If you add a new script to the head, it will be executed once loaded. This is true for any script. If it doesn't, it means the script has a guard that prevents running the same code again most likely by checking if one of its variables is already defined.
In the case of Facebook SDK, it will check if FB is already defined globally so you simply need to delete it before adding your new sdk script with a different locale.
My code looks a bit different, but I'm also using Nuxt:
<template>
<div
:key="`fb-chat-${$i18n.locale}`"
class="fb-customerchat"
:page_id="pageId"
theme_color="#4586ff"
greeting_dialog_display="hide"
:logged_in_greeting="$t('greeting')"
:logged_out_greeting="$t('greeting')"
></div>
</template>
<script>
export default {
name: 'FacebookChat',
data() {
return {
pageId: process.env.FACEBOOK_PAGE_ID,
}
},
watch: {
'$i18n.locale': 'resetFacebookSdk',
},
mounted() {
this.initFacebookSdk()
},
methods: {
initFacebookSdk() {
if (!process.browser) return
const locale = this.$i18n.locale === 'de' ? 'de_DE' : 'en_US'
delete window.FB // needs to be undefined when inserting a second script with different locale
window.fbAsyncInit = function () {
window.FB.init({
appId: process.env.FACEBOOK_APP_ID,
autoLogAppEvents: true,
xfbml: true,
version: 'v10.0',
})
}
;(function (d, s, id) {
let js = d.getElementById(id),
fjs = d.getElementsByTagName(s)[0]
if (js) js.parentNode.removeChild(js) // remove script tag if exists
js = d.createElement(s)
js.id = id
js.src = `https://connect.facebook.net/${locale}/sdk/xfbml.customerchat.js`
fjs.parentNode.insertBefore(js, fjs)
})(document, 'script', `facebook-jssdk-${this.$i18n.locale}`)
},
resetFacebookSdk() {
const fbRoot = this.$el.closest('#fb-root')
if (!fbRoot) return
// Move fb-customerchat element outside of fb-root (created by Facebook SDK)
fbRoot.parentNode.insertBefore(this.$el, fbRoot)
// Delete fb-root to let Facebook SDK create it again
fbRoot.parentNode.removeChild(fbRoot)
this.initFacebookSdk()
},
},
}
</script>
What you should pay attention to:
The locale is part of the key attribute of my element to make it re-render on locale change in order to remove what the sdk has added (attributes, child elements)
There is a watcher to call resetFacebookSdk on locale change
I modified the sdk code snippet to remove the script tag if it was already present instead of doing nothing. This way, we can create it again.
The element .fb-customerchat is cleaned up with the key attribute, but the sdk has wrapped it with a new element #fb-root. The method resetFacebookSdk is taking care of moving .fb-customerchat outside of that wrapper and deleting it.
You can see it in action on our website (you can switch language in the footer).
Hope it helps. Let me know if something is not clear.

I solved it by using this.$router.go(0); on the button click of the language switch, i had hoped to use another way, but still could'nt find one, anyway, now the language changes when the page reloads and the sdk's lang code as well, if else uses the appropriate language. Maybe i ll find a more elegant solution someday 😊👍

Related

How to Customize Facebook Customer Chat Plugin (beta)

I know the Customer Chat Plugin is only in beta mode, but I would love to use it if I can. After looking over the docs, I can't seem to find a way to customize the functionality of the chat widget.
Here's what I want to do:
Show and hide the widget programmatically (javascript)
Tap into close event of widget to hide the whole widget instead of just minimizing the chat window.
Toggle between more than one widget
Background:
Website is a marketplace of sellers, and I want to be able to give them all a personal chat feature that connects consumers with the sellers.
Previous attempts:
Hide and show widget by targeting #fb-root and applying display: none; or display: block;. This works okay, but still really hacky and doesn't solve problem of knowing when to trigger hiding and showing (usually on a button click "chat now", but I also want the widget to hide when closed/minimized).
Tried loading two widgets at same time, but one the first one ever loads, and even if the second one did load, I wouldn't have the ability to only target one at a time due to my id DOM selector.
index.html (inside head):
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'first-app-id',
autoLogAppEvents : true,
xfbml : true,
version : 'v2.12'
});
};
(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.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'second-app-id',
autoLogAppEvents : true,
xfbml : true,
version : 'v2.12'
});
};
(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.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
index.html (inside body):
<div class="fb-customerchat"
page_id="first-page-id"
logged_in_greeting="Hello, my name is Kevin :)"
logged_out_greeting="Hey, you are not logged in! You should log in.">
</div>
<div class="fb-customerchat"
page_id="second-page-id"
logged_in_greeting="Hello, my name is Kevin again :)"
logged_out_greeting="Hey, you are not logged in! You should log in.">
</div>
Any suggestions, tips, or hacks are greatly appreciated.
UPDATE:
I have confirmed that toggling between more than one widget is impossible at this point. However, it should be possible to do the other two things. Because it's just a beta release, custom event handling and such is not supported. I will wait for the official release.
This may not have been available at the time you posted your question, however the Facebook Customer Chat SDK should help accomplish what you are after.
To load the Customer Chat SDK instead of the standard SDK update the following line:
js.src = "https://connect.facebook.net/en_US/sdk.js";
to
js.src = "https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js";
To show and hide the widget then add the following in your JS:
FB.CustomerChat.show(shouldShowDialog: boolean);
FB.CustomerChat.hide();
You can also subscribe to event, so to hide the whole widget you could try the following:
FB.Event.subscribe('customerchat.dialogHide',
FB.CustomerChat.hide();
);
See the FB developer docs for the full details: https://developers.facebook.com/docs/messenger-platform/discovery/customer-chat-plugin/sdk/
Hope that helps. I have been wrestling with the Facebook Customer Chat Plugin for the last couple of days!

Facebook share with static og tags and no app

I'm trying to achieve a facebook share of a questionnaire results page.
I want the following items to be custom
1) The button, so I'm using an image
2) The Title, description and Image that appears in the Share box
3) The URL that is shared.
Here's the problem. The results are sent to a page called /results. This page changes depending on the visitors cookie (the results of their questionnaire is placed in this cookie so it displays the appropriate result).The OG tags for this page are also populated to get the right image, title and description to appear in the search box, but if Facebook were to scrape this page, it wouldn't be the same.
Here is the code I'm using
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '<?=FB_APP_ID?>',
xfbml : true,
version : 'v2.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 = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
<img src="images/icons/share-fb.png" alt="Share your Results on Facebook" class="share"/>
$('.share').click(function(){
FB.ui({
method: 'share',
href:'http://example.net/results',
}, function(response){});
});
Is it at all possible to
1) Do this without having a Facebook App? Under FBs new rules I'm unable to get an app approved without the need for Facebook login which I neither need nor have.
2) Set what is shared and not have it change in a user's feed whenever facebooks scrapes the result page and doesn't see the relevant OG tags?

How to get bigger images in News Feed when sharing a link

I have a page that uses the Facebook Feed and Share dialog. I read on this page of documentation that there is a way to get bigger images into the news feed, rather than the typical thumbnail. https://developers.facebook.com/docs/opengraph/howtos/maximizing-distribution-media-content/#images
I am not sure what I'm doing wrong but my image never appears to be in the larger format. Its always the tiny thumbnail. Here is the code I have. Not really sure what I'm doing wrong.
At first I thought my share.jpg image was too big (it was around 1900x1200) so I sized it down to the min specs that Facebook said to use (1200x630) and I still end up with the tiny thumbnail.
This is the FB.ui function that I have..
$(".facebook").bind("click", function(event){
event.preventDefault();
FB.ui({
method: 'feed',
//link: encodeURIComponent(shareURL),
link: shareURL,
caption: 'An example caption',
picture: 'http://www.example.com/beta/share.jpg'
}, function(response){});
});
Here's what I have on the page right after <body>
<script>
window.fbAsyncInit = function() {
// init the FB JS SDK
FB.init({
appId : 'XXXXXXXXXXXX', // App ID from the app dashboard
channelUrl : '//www.example.com/beta/channel.html', // Channel file for x-domain comms
status : true, // Check Facebook Login status
xfbml : true // Look for social plugins on the page
});
// Additional initialization code such as adding Event Listeners goes here
};
// Load the SDK asynchronously
(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 = "//connect.facebook.net/en_US/all.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
I think I may have figured it out. Looks like the bigger image only works on mobile and the new News Feed (which I still don't have.. WTF? LOL)

Facebook Comments - height is clipped

I'm using the older FB xfbml Comment module on my site (I'd upgrade were it not for problems with migration), with this code to embed it
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxxxxxxx',
channelUrl : '//www.site_etc.com/channel.html',
status : true,
cookie : true,
xfbml : true
});
FB.Canvas.setAutoGrow();
}
(function(d){ var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0]; if (d.getElementById(id)) {return;} js = d.createElement('script'); js.id = id; js.async = true; js.src = "//connect.facebook.net/en_US/all.js"; ref.parentNode.insertBefore(js, ref); }(document));
The problem I'm having is that whenever FB loads the Comments iframe, it is clipped in height. It consistently loads with a height of about 160px, no matter how many comments etc. there are, and I'm not able to get it to expand accordingly. I'm fairly certain there is no conflicting CSS, containers, etc.
I have no idea what is going on nor where to begin searching for this. Google had a few interesting hits but ultimately no solution -
http://bit.ly/11JzGh8

fb:comment is setting wrong height (cuts comments in half)

I'm building a GWT application and am trying to dynamically add facebook comment boxes in certain places. This is working fine, except that the facebook SDK isn't calculating the height correctly. It always sets it at 160px.
This means that only half of the first comment is visible, even if there are multiple comments (i.e. it gets visibly cut in half). If I use the same code outside of GWT it works fine (i.e. the height is calculated correctly).
Does anybody know how the facebook SDK calculates the height of the box? Or what else I can try?
The details:
I initialise the facebook SDK as follows:
public static native void initFacebookSDK()
/*-{
window.fbAsyncInit = function() {
// init the FB JS SDK
FB.init({
appId : '<my-app-id>', // App ID from the App Dashboard
channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File for x-domain communication
status : true, // check the login status upon init?
cookie : true, // set sessions cookies to allow your server to access the session?
xfbml : true
// parse XFBML tags on this page?
});
// Additional initialization code such as adding Event Listeners goes here
};
// Load the SDK's source Asynchronously
(function(d, debug) {
var js, id = 'facebook-jssdk', ref = d
.getElementsByTagName('script')[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement('script');
js.id = id;
js.async = true;
js.src = "//connect.facebook.net/en_US/all"
+ (debug ? "/debug" : "") + ".js";
ref.parentNode.insertBefore(js, ref);
}(document, false));
}-*/;
I add the div as follows:
//_root is a vertical panel
_root.add(new HTML("<div id=\"mydiv\"></div>"));
and then I populate the div like this:
public static native void showComments(String currentUrl_)
/*-{
var mydiv = $doc.getElementById('mydiv');
mydiv.innerHTML = "<fb:comments href='" + currentUrl_
+ "' num_posts='5' width='422'></fb:comments>";
FB.XFBML.parse(mydiv);
}-*/;
The problem is that the facebook SDK always populates the div with the following:
<span style="height: 160px; width: 422px;">
<iframe ...>...</iframe>
</span>
whereas if I don't use GWT, the height parameter changes appropriately, e.g:
<span style="height: 1469px; width: 422px;">
<iframe ...>...</iframe>
</span>
Hope someone can help.
Worked it out.
In JSNI I should be using $doc and $wnd, instead of document and window, respectively. https://developers.google.com/web-toolkit/doc/latest/DevGuideCodingBasicsJSNI#writing
In my defence I had tried this, but the missing ingredient was that I needed to reference the FB object as $wnd.FB, e.g:
$wnd.FB.init(...) and $wnd.FB.XFBML.parse(...)
Hope this helps someone.