lintpageincident.log
checksenvironmentstoolsblogfaq
sign inget started
~/blog/open-graph-tags-guide
SEOOpen GraphSocial Media

Open Graph Tags: What Happens When You Skip Them

Marius Orzaru·February 3, 2026·8 min read·updated August 29, 2026

What your links look like when you're not looking

You spend weeks building a beautiful landing page. Then someone shares it on Slack, and the preview shows... nothing. No image, no title, just a bare URL. That's what happens when you skip Open Graph tags.

Open Graph (OG) tags are meta tags that control how your page appears when shared on social media, messaging apps, and anywhere else that generates link previews. Without them, platforms guess what to show - and they usually guess wrong. An open graph checker renders the preview exactly as Slack, LinkedIn, and Facebook will build it, so you find out before your audience does.

The four essential OG tags

At minimum, every page should have these four tags:

<meta
  property="og:title"
  content="LintPage - Pre-Launch SEO Linting"
/>
<meta
  property="og:description"
  content="Catch SEO disasters before launch."
/>
<meta
  property="og:image"
  content="https://lintpage.com/og-image.png"
/>
<meta
  property="og:url"
  content="https://lintpage.com/"
/>
  • og:title - The headline in the link preview. Can differ from your <title> tag (and often should - social titles can be more conversational).
  • og:description - The supporting text below the title. Keep it under 200 characters.
  • og:image - The preview image. This is the single biggest factor in whether someone clicks a shared link.
  • og:url - The canonical URL for the content. Helps platforms deduplicate shares.

Getting the image right

The og:image is the most impactful tag and the most commonly broken. Here's what you need to know:

Size: 1200x630 pixels (1.91:1 aspect ratio). This works across Facebook, Twitter, LinkedIn, and Slack. Some platforms crop slightly, so keep important content centered.

Format: Use PNG or JPG. Keep the file size under 5MB. Some platforms won't load images over 8MB.

URL: Must be an absolute URL starting with https://. Relative paths don't work. The image must be publicly accessible - platforms fetch it from their servers, not from the user's browser.

<!-- Won't work: relative path -->
<meta
  property="og:image"
  content="/images/og.png"
/>

<!-- Will work: absolute URL -->
<meta
  property="og:image"
  content="https://example.com/images/og.png"
/>

Generating OG images dynamically

Hand-making an image per post does not scale. Next.js can render one per route at request time using JSX, which means the image stays in sync with the content automatically. Create opengraph-image.tsx beside the page:

import { ImageResponse } from 'next/og';

export const size = { width: 1200, height: 630 };
export const contentType = 'image/png';

export default async function Image({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  const post = await getPost(slug);

  return new ImageResponse(
    (
      <div
        style={{
          width: '100%',
          height: '100%',
          display: 'flex',
          flexDirection: 'column',
          justifyContent: 'center',
          padding: 80,
          background: '#0a0a0a',
          color: '#e7ecf3',
          fontSize: 64,
        }}
      >
        <div style={{ fontSize: 24, opacity: 0.6 }}>example.com</div>
        <div>{post.title}</div>
      </div>
    ),
    { ...size },
  );
}

Next.js generates the file, serves it, and injects the matching og:image tags with the correct absolute URL and dimensions. Two things to know: the route name carries a build-specific hash, so old URLs 404 after a deploy (harmless - crawlers refetch from the tag), and only a subset of CSS is supported, so keep the layout to flexbox, solid colours, and text.

What each platform actually shows

"Open Graph" is a shared vocabulary, not a shared renderer. The same four tags produce noticeably different cards depending on where the link lands, which is why a preview that looks right in one place can look broken in another.

  • Slack shows a compact card with a coloured left border. It reads og:site_name, og:title, og:description, and a thumbnail. Long descriptions are truncated hard at roughly two lines, so front-load the meaning.
  • LinkedIn uses a large image with the title beneath it and the domain in small caps. It ignores og:description entirely in the feed. If your title doesn't carry the message on its own, LinkedIn will not carry it for you.
  • Facebook renders the closest thing to the "reference" card: large image, title, description, domain. It is also the strictest about image dimensions and the most aggressive about caching.
  • X/Twitter uses twitter:card to pick the layout and falls back to OG tags for content. Without twitter:card, you get the small square thumbnail rather than the large image.
  • iMessage and WhatsApp fetch the image directly from the client on some platforms rather than from a central scraper. An image behind a CDN rule that blocks unknown user agents will silently fail here while working everywhere else.
  • Discord is the most forgiving and will fall back to an inline image if OG tags are missing entirely, which is why a link can look fine in Discord and bare everywhere else.

The practical consequence: write og:title so it stands alone, keep og:description under about 120 characters if you care about Slack, and always set twitter:card.

Twitter Card tags

Twitter (X) has its own set of meta tags that override OG tags when present:

<meta
  name="twitter:card"
  content="summary_large_image"
/>
<meta
  name="twitter:title"
  content="LintPage - Pre-Launch SEO Linting"
/>
<meta
  name="twitter:description"
  content="Catch SEO disasters before launch."
/>

The twitter:card value determines the preview layout:

  • summary - small square image on the left, title and description on the right
  • summary_large_image - large image above the title and description (this is what you usually want)

If you don't set Twitter-specific tags, Twitter falls back to your OG tags. But setting twitter:card is important because there's no OG equivalent - without it, Twitter defaults to the small summary format.

Tagging blog posts and articles

For content pages, og:type: article unlocks a few extra fields that some platforms surface and that search engines read as corroborating signals:

<meta property="og:type" content="article" />
<meta property="article:published_time" content="2026-03-14T09:00:00.000Z" />
<meta property="article:modified_time" content="2026-08-29T11:20:00.000Z" />
<meta property="article:author" content="https://example.com/about" />
<meta property="article:section" content="SEO" />

Use ISO 8601 timestamps. article:modified_time should reflect a real content change - moving it on every deploy is the same fake-freshness signal that gets lastmod in your sitemap ignored.

In Next.js these map onto the openGraph object directly:

export const metadata: Metadata = {
  openGraph: {
    type: 'article',
    publishedTime: '2026-03-14T09:00:00.000Z',
    modifiedTime: '2026-08-29T11:20:00.000Z',
    authors: ['https://example.com/about'],
  },
};

Common mistakes

1. Forgetting og:type

While not required, og:type helps platforms understand your content:

<meta
  property="og:type"
  content="website"
/>
<!-- Or for blog posts -->
<meta
  property="og:type"
  content="article"
/>

2. Stale cached previews

Platforms cache link previews aggressively (sometimes for weeks). If you update your OG tags but the preview doesn't change, confirm the new tags are actually live with an og tag checker first - then use the platform's debug tool to force a refresh:

  • Facebook: Sharing Debugger
  • LinkedIn: Post Inspector
  • Twitter/X: Card Validator was deprecated — post a test tweet or use a third-party preview tool instead

3. Missing og:site_name

This tag shows the site name in a smaller font above the title in some platforms:

<meta
  property="og:site_name"
  content="LintPage"
/>

It's a subtle branding touch that makes your shared links look more professional.

§ try this tool
Open Graph Tag Preview
Check your Open Graph and Twitter Card tags for social media sharing.
try it free →

When the preview is wrong: check in this order

Most "my OG tags are broken" reports come down to one of five things, and they're worth ruling out in this sequence:

  1. Is the tag in the server-rendered HTML? View source, don't inspect the DOM. Tags injected by client-side JavaScript are invisible to every scraper - they do not run your JS.
  2. Is og:image an absolute URL? Relative paths silently produce no image. It must start with https://.
  3. Is the image publicly reachable? Fetch it in a private window with no session. Scrapers have no cookies, and an image behind auth or a CDN bot rule will 403.
  4. Is the platform showing you a cached copy? Facebook and LinkedIn cache aggressively, sometimes for weeks. Run the platform's own debugger to force a refetch.
  5. Is something overriding your tags? Duplicate og: tags, a CMS plugin, or a framework default can append a second set. Scrapers generally take the first occurrence, which may not be yours.

An og tag checker collapses the first three into one request by fetching the page the way a scraper does and reporting exactly what came back.

Setting up OG tags in Next.js

Next.js makes OG tags straightforward through the Metadata API:

export const metadata: Metadata = {
  openGraph: {
    title: 'My Page Title',
    description: 'My page description',
    url: 'https://example.com/my-page',
    type: 'website',
    siteName: 'My Site',
  },
  twitter: {
    card: 'summary_large_image',
    title: 'My Page Title',
    description: 'My page description',
  },
};

For dynamic OG images, create an opengraph-image.tsx file in your route directory. Next.js will automatically generate and serve the image, and add the appropriate meta tags.

Check your tags before sharing

The frustrating thing about OG tags is that you only discover they're broken after sharing a link publicly. By then, the ugly preview is already in the Slack channel or the tweet is live.

Run your URL through the LintPage Open Graph Checker before you share. It shows you exactly what your link preview will look like and flags any missing or misconfigured tags. Fix them before anyone sees the broken version.

OG tags are one slice of a larger set. The same <head> block holds your title, description, canonical, and robots directives, so it's worth reading how to write meta tags that actually improve your SEO and running a meta tag checker over the same page while you're there.

§ about the author
Marius OrzaruFounder, LintPage (BludeskSoft)

I built LintPage after a single stray noindex tag slipped into production and quietly cost us 47 days of organic traffic. It now runs the 60 automated checks I wish we had run before that deploy.

LinkedIn →

Get notified when we publish new posts.

§ run all 60 checks at once

Want the full picture? Stop checking one thing at a time.

Get a complete pre-launch SEO audit of your site with a single click.

run a full audit →
lintpage

Pre-launch SEO linting for developers. Catch disasters before they ship.

Product

  • Overview
  • Pre-launch checks
  • Full audit

Free tools

  • Meta tag checker
  • Robots.txt validator
  • AI crawler checker
  • OG preview
  • Sitemap validator
  • Heading checker
  • SSL checker
  • Redirect checker
  • Structured data validator
  • Broken link checker
  • Core Web Vitals checker
  • Security headers checker
  • Canonical tag checker
  • All tools →

Resources

  • Blog
  • About
  • RSS feed
  • Contact

Legal

  • Privacy
  • Terms
© 2026 lintpage. All rights reserved.built after one too many post-mortems.