Search SpacerrApps

Find an app or a write-up by title

All guides

Open Graph tags for your app: the link preview checklist

Every time someone shares your link, the preview is your ad. Here are the tags that control it, the image size that works everywhere, and how to force a stale one to update.

Written by
SpacerrApps
Published
Reading time
4 min read

When someone pastes your link into X, LinkedIn, Slack, Discord, iMessage or WhatsApp, the app fetches your page and builds a card from a handful of tags in the page's head. Those tags are Open Graph, a format Facebook introduced and everyone else adopted.

Get them right and a shared link becomes a small ad with your name, your pitch and a picture. Get them wrong and it is a bare URL, or worse, a card with your cookie banner as the image.

The short answer

Put these in the head of every page, with absolute URLs:

<meta property="og:title" content="YourApp: a focus timer for Mac" />
<meta property="og:description" content="A menu bar timer that blocks distracting sites while it runs." />
<meta property="og:image" content="https://yourapp.com/og.png" />
<meta property="og:url" content="https://yourapp.com/" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary_large_image" />

Make the image 1200 by 630 pixels, PNG or JPG, under a few hundred kilobytes. That is the whole checklist. The rest of this guide is the detail behind each line.

The tags, one at a time

og:title

The bold line on the card. It does not have to match your page title: the page title is written for a search result, the card title for a feed. Keep it under about 60 characters so it does not get cut, and lead with the product name.

og:description

The grey line under the title. One sentence on what the product does, for whom. Some platforms show two lines, some show none, and X shows none on a large image card, so never put anything essential only here.

og:image

The picture, and the part that decides whether anyone clicks. It must be an absolute URL starting with https, not a path like /og.png. A relative path is the single most common reason a preview shows no image.

og:url

The canonical address of the page. Platforms use it to group shares of the same page, so point it at the one version you want counted, the same one your canonical tag names.

og:type

website for the home page and most product pages, article for a blog post. It changes little in practice, but a missing type is one more warning in every debugger.

twitter:card

X reads the Open Graph tags for the title, description and image, and only needs this one extra tag to choose the layout. summary_large_image gives you the full width picture. summary gives you a small square thumbnail beside the text, which almost always looks worse for a product. You only need twitter:title and friends if you want X to show something different from everywhere else.

The image

Size. 1200 by 630 pixels, a ratio of 1.91 to 1. Facebook, LinkedIn, Slack and Discord all display it well, and X crops it only slightly for its 2 to 1 large card. Build the image with a little margin on every side so that crop never cuts your text.

Format and weight. PNG for screenshots and text, JPG for photographs. Keep it small: some platforms give up on a slow image and show the card without it. X's own limit is 5 MB, but aim far below that.

What to put on it. Your product name, one line saying what it does, and either the product itself or your logo. Text large enough to read on a phone, because that is where most previews are seen. A screenshot of your whole dashboard shrunk to a thumbnail reads as noise.

One per page, if you can. A blog post with its own title on the image gets shared more than one that reuses the home page picture. On Next.js, an opengraph-image.tsx file beside a route generates that route's image from JSX at build or request time, so every page can have one without anyone opening a design tool.

Why a preview shows the wrong thing

It is cached. Every platform stores the card the first time it sees a URL and does not look again for a while. Fix the tags, then force a refresh:

  • Facebook and WhatsApp: the Sharing Debugger, then Scrape Again.
  • LinkedIn: the Post Inspector, which refetches on every inspection.
  • X, Slack, Discord and iMessage have no public refresh button. Change the image's URL instead, for example /og.png?v=2, and the next share fetches it fresh.

The tags are added by JavaScript. The fetchers that build previews mostly do not run JavaScript. If your head tags are injected in the browser, the card never sees them. Render them into the HTML on the server.

The page needs a login or blocks bots. A preview fetcher is a bot with no cookies. If your page redirects it to a sign-in screen, or a firewall rule blocks unknown user agents, the card is built from the wrong page or from nothing.

The image URL is relative, or on http. Absolute and https, every time.

Where it matters most for an app

Three pages get shared far more than the rest, and each deserves its own card:

  1. The home page. What gets pasted in every launch post and reply.
  2. Your launch and listing pages elsewhere. On a directory or launch site the card is built from their tags, not yours, which is one reason a clear listing description matters.
  3. Blog posts and changelogs. Each one is a fresh reason to share the link, and a fresh chance for a good card.

Open Graph decides how your link looks when a person shares it. Two neighbouring files decide how your product reads to machines: SoftwareApplication schema for search engines, and llms.txt for AI answer engines. A product site should have all three.