Previous Article
Submitting a Form to PHP with JavaScript (AngularJS Is End-of-Life)
16 September 2018
Facebook's social plugins have changed a great deal since the "add this snippet" era. Some were retired, the SDK version in every old tutorial no longer exists, and the whole thing now carries a privacy cost worth weighing before you embed it.
This guide covers what still works in 2026, what to use instead of what does not, and how to set it up correctly.
version: 'v2.3' — as the original of this article did — references something that stopped working years ago. You must use a current version.For sharing, no — and this is the most useful thing to know. A plain share link needs no SDK, no App ID, and sets no cookies:
<a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fexample.com%2Fpost" target="_blank" rel="noopener noreferrer"> Share on Facebook </a>
What the shared post looks like is controlled entirely by your Open Graph tags, not by any button:
<meta property="og:title" content="Your article title" /> <meta property="og:description" content="A one-line summary." /> <meta property="og:image" content="https://example.com/og/cover.png" /> <meta property="og:url" content="https://example.com/post" /> <meta property="og:type" content="article" />
Use an absolute og:image URL sized 1200×630. If you change it later, Facebook caches the old one — clear it with the Sharing Debugger at developers.facebook.com/tools/debug.
For most sites this is the whole job. Reach for the SDK only when you specifically need the Page plugin or Comments.
The Page plugin and Comments plugin require a registered app.
Never put the App Secret in client-side code. The original article exposed a real App ID in a public tutorial; that alone is low-risk, but the same carelessness with a secret is account compromise. The secret stays server-side, always.
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function () {
FB.init({
appId: 'YOUR_APP_ID',
xfbml: true,
version: 'v21.0', // use a CURRENT version — check the changelog
});
};
</script>
<script async defer crossorigin="anonymous"
src="https://connect.facebook.net/en_US/sdk.js"></script>
Two upgrades over the old snippet. The modern async defer script tag replaces the hand-rolled DOM-insertion function every 2018 tutorial used. And https:// is explicit rather than the protocol-relative //connect.facebook.net, which is a relic from when sites still served over HTTP.
Check the Graph API changelog for the current version rather than copying v21.0 from here — it will itself be out of date eventually.
<div class="fb-share-button"
data-href="https://example.com/post"
data-layout="button"
data-size="large"></div>
Honestly, the plain link shown earlier is the better choice — it loads nothing, tracks nobody, and looks however you style it. Use this XFBML version only if you specifically want Facebook's own button styling.
Embeds a Facebook Page's feed, likes and a follow button:
<div class="fb-page"
data-href="https://www.facebook.com/YourPage"
data-tabs="timeline"
data-width="360"
data-height="500"
data-small-header="false"
data-hide-cover="false">
<blockquote cite="https://www.facebook.com/YourPage" class="fb-xfbml-parse-ignore">
<a href="https://www.facebook.com/YourPage">Visit our Facebook Page</a>
</blockquote>
</div>
The <blockquote> inside is a fallback — it shows a plain link if the SDK is blocked or fails, which for a Facebook embed is fairly often.
<div class="fb-comments"
data-href="https://example.com/post"
data-width="100%"
data-numposts="5"></div>
Think carefully before using this one. It only lets people comment if they have a Facebook account and are logged in, it loads a large third-party bundle, it sets tracking cookies, and you do not own the comment data — it lives on Facebook. A self-hosted comment system, or a privacy-focused service, is usually the better call.
If you inject plugin markup after the page has loaded — in a single-page app, say — the SDK will not have parsed it. Re-parse manually:
// After adding .fb-* elements to the DOM
if (window.FB) {
FB.XFBML.parse(newContainerElement);
}
Scope the parse to the new container rather than re-parsing the whole document, which is wasteful and can flicker existing plugins.
Embedding any Facebook plugin loads Facebook's script and lets it set cookies for every visitor, whether or not they interact — which is third-party tracking of your users, on your site, on your behalf.
Consequences worth taking seriously:
The privacy-conscious pattern is to load the SDK only after consent, and only when a plugin is actually on screen:
function loadFacebookSDK() {
if (document.getElementById('facebook-jssdk')) return;
const js = document.createElement('script');
js.id = 'facebook-jssdk';
js.async = true;
js.defer = true;
js.crossOrigin = 'anonymous';
js.src = 'https://connect.facebook.net/en_US/sdk.js';
document.body.appendChild(js);
}
// Call only once the user has accepted marketing cookies.
if (getConsent('marketing') === 'accepted') {
loadFacebookSDK();
}
| Want | Better than the SDK |
|---|---|
| Sharing | Plain sharer.php link + Open Graph tags |
| Comments | Self-hosted, or a privacy-focused service |
| Show your feed | A static screenshot or a periodic server-side fetch |
| Login with Facebook | Facebook Login via OpenID Connect, server-side |
Advertisement
Written by
Amit VermaFounder / Senior Software Engineer
Amit leads engineering at Being Idea. With 15+ years building scalable software products across global markets, he drives architecture decisions and engineering culture across every engagement.
More articles by AmitYou might also like
We ship software that scales. Let's work together.