The Open Graph protocol has become the standard mechanism for sharing rich content on the web.
In this guide, we’ll show you how to implement Open Graph tags for sharable previews (often called social media previews), introduce you to the tools you can use, and also examine the different platform rendering issue.
You may have noticed that when you share a URL, the platform on which you’re sharing displays a preview of the link.
Here’s an example of what happens when I share a link to a blog on Twitter:
Sharing a link automagically generates a preview card at the bottom of the tweet. It contains an image, the title of the blog, and a description of the post as well.
Aside from looking pretty fabulous, this preview gives the reader of the tweet some fairly rich information about what might be in that post. It potentially saves them a click if it’s obvious that the post isn’t particularly interesting to them. Conversely, it increases the likelihood that the reader will click if it does seem intriguing. Sharing previews is an asset.
Twitter made this card using a combination of Open Graph meta tags and some custom tags that my blog surfaces.
The Open Graph protocol, introduced by Facebook, describes itself as follows:
The Open Graph protocol enables any web page to become a rich object in a social graph. For instance, this is used on Facebook to allow any web page to have the same functionality as any other object on Facebook.
Open Graph is all about meta tags — specifically, adding meta tags to an HTML page to explicitly define pieces of standardized information. There are many purposes for this, but for this tutorial, we’ll focus solely on sharing.
Now that we understand what sharing previews give us, let’s demonstrate how they work.
The Open Graph website has a great walkthrough of the minimum requirement for Open Graph:
og:title
is the title of your object as it should appear within the graph — e.g., “The Rock”og:type
is the type of your object — e.g., “video.movie.” Depending on the type you specify, other properties may also be requiredog:image
is an image URL that should represent your object within the graphog:url
is the canonical URL of your object that will be used as its permanent ID in the graph — e.g., “https://www.imdb.com/title/tt0117500/”.
As an example, the following is the Open Graph protocol markup for The Rock on IMDB:
<html prefix="og: https://ogp.me/ns#"> <head> <title>The Rock (1996)</title> <meta property="og:title" content="The Rock" /> <meta property="og:type" content="video.movie" /> <meta property="og:url" content="https://www.imdb.com/title/tt0117500/" /> <meta property="og:image" content="https://ia.media-imdb.com/images/rock.jpg" /> ... </head> ... </html>
Sharing previews have very similar, but crucially slightly different, requirements. Five tags are required to generate a sharable preview:
og:title
, the title of your pageog:description
, a description of the content of that pageog:image
, an image URL that should appear in the social media shareog:url
, the canonical URL of your web page.twitter:card
, a custom tag that is only required by Twitter indicating the type of share, be it "summary"
, "summary_large_image"
, "app"
, or "player"
—probably "summary"
or "summary_large_image"
for most use casesIf we implement these, our page will offer sharable previews.
With this understanding in place, let’s see what it would look like to add sharable previews to a website. We’ll make ourselves a React website with:
npx react-static create
When prompted, name the site demo
and select the blank
template.
Nothing we’re doing here is React-specific; it’s applicable to all websites regardless of the technology they’re built with; this is just a straightforward way to demo a website.
We’re using React Static for this demo because it is a static site generator. This is significant because, as a general rule, many platforms that support sharing do not crawl dynamically generated meta tags. By this we mean tags generated by JavaScript at runtime.
Rather, these tags must be baked into the HTML that is served up. One way to tackle this is by dynamically serving up the meta tags from the server. Another way to ensure that tags are in the built HTML in the first place. This is exactly what a static site generator such as React Static does.
We’re going to replace the App.js
that is scaffolded out with our own App.js
:
import * as React from 'react'; import { Head } from 'react-static'; import './app.css'; function App() { const openGraphData = { title: 'Open Graph: a guide to sharing previews', description: 'This page features the Open Graph protocol markup for sharing previews.', url: 'https://johnnyreilly.github.io/open-graph-sharing-previews/', image: 'https://upload.wikimedia.org/wikipedia/commons/7/72/Open_Graph_protocol_logo.png', }; return ( <div className="App"> <Head> <meta property="og:title" content={openGraphData.title} /> <meta property="og:description" content={openGraphData.description} /> <meta property="og:url" content={openGraphData.url} /> <meta property="og:image" content={openGraphData.image} /> <meta name="twitter:card" content="summary" /> </Head> <h1>{openGraphData.title}</h1> <img src={openGraphData.image} alt="The Open Graph protocol logo" /> <h2>Share it and see!</h2> </div> ); } export default App;
The code above renders the required meta tags for sharing previews. When we build and deploy this, we can see they show up like so:
Now that we have a demo, it would be tremendous to be able to test it out. The following social platforms have official tools to test your URLs:
There’s also a number of unofficial aggregator tools that attempt to render the appearance of your social previews across multiple platforms to save you to hassle of going to each tool in turn. Some standouts include:
Let’s test out the Twitter validator:
Terrific! We have sharable previews enabled for the site we’ve made. Now we have a sense of what sharing previews look like, what powers them and how to implement them.
So far, we’ve only looked at Twitter for examples of sharing previews. However, support for Open Graph sharing previews is widespread.
Examples of other places where you can use sharing previews include Facebook, Polywork, Slack, Teams, LinkedIn, Outlook.com, Discord — the list is very long indeed and growing.
However, each platform implements sharing previews according to their own standard. What does mean? Well, a link shared on Twitter will look different from one shared on Outlook. For example:
Above, I’m sharing a link to a blog post. The image is to the left and the title and description are to the right.
Now let’s look at the same link shared on Twitter:
Here, the image is above the title and the description. More distressingly, the image has been cropped, which renders the title slightly unreadable. So while the mechanism for sharing is roughly standardized, the rendering is not.
It’s not dissimilar to the web in the year 2000. Back then, a single piece of HTML could be rendered in many different ways, depending on the browser. The same is true now for Open Graph sharing. Sharing can look very different depending on the platform that is displaying the preview.
The only way to avoid this at present is to test thoroughly on all the platforms where you want to share links to ensure the sharable previews look acceptable.
In this guide, we introduced you to the concept of sharable previews, demonstrated how to add sharable previews to a website and how to test them, and reviewed some of the rough edges to be aware of.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.