Why the description matters
The description is the grey text under the title. It tells people what they’ll get before they click, and a card without one looks unfinished. Platforms read it from og:description. Facebook falls back to your <meta name="description"> when it’s missing, but other platforms may show nothing, so set both.
Where it shows, and how much
- Facebook and WhatsApp show about 160 characters, often fewer on phones.
- Slack shows up to about 300 and Discord about 350.
- Telegram shows about 200.
- LinkedIn’s feed card shows no description, and X’s large image card doesn’t either. They still read it, so it’s worth setting.
The checker flags descriptions over 200 characters. The cheat sheet compares the limits across platforms.
Writing a good one
- Say what the reader gets, not what the page is. “How we halved our build time” beats “Our blog post about builds”.
- Put the important words in the first 100 characters, so a cut-off still makes sense.
- Don’t repeat the title. The two sit next to each other, so the description should add something.
- Write one per page. A site-wide description on every page makes all your links look the same.
Common reasons it’s missing
- Only a meta description is set
- Facebook uses it, other platforms may not. Add
og:descriptionwith the same text. - Neither tag is set
- The card has no summary line anywhere. Add both tags from the quick fix above.
- The tag is empty
- A template that writes
content=""when a post has no excerpt counts as missing. Fall back to the first sentence of the content rather than leaving it empty. - The tag is added by JavaScript
- Crawlers don’t run JavaScript. See why your app’s links show a blank preview.
Code for your framework
These set both descriptions together with the other tags a preview needs. In Next.js, an openGraph object without a description uses the page’s description, so setting it once can be enough.
HTML inside <head>
<title>How we cut our build time in half</title>
<meta name="description" content="What we changed in our CI pipeline, and what it saved.">
<link rel="canonical" href="https://example.com/blog/faster-builds">
<!-- Open Graph -->
<meta property="og:title" content="How we cut our build time in half">
<meta property="og:description" content="What we changed in our CI pipeline, and what it saved.">
<meta property="og:url" content="https://example.com/blog/faster-builds">
<meta property="og:type" content="article">
<meta property="og:site_name" content="Example Blog">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="https://example.com/images/faster-builds.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="A chart of build times dropping from 12 to 6 minutes">
<!-- X (Twitter). X falls back to the og: tags for title, description and image. -->
<meta name="twitter:card" content="summary_large_image">
Next.js (App Router) in page.tsx or layout.tsx
import type { Metadata } from "next";
// app/<route>/page.tsx (or layout.tsx)
export async function generateMetadata(): Promise<Metadata> {
return {
title: "How we cut our build time in half",
description: "What we changed in our CI pipeline, and what it saved.",
alternates: { canonical: "https://example.com/blog/faster-builds" },
openGraph: {
title: "How we cut our build time in half",
description: "What we changed in our CI pipeline, and what it saved.",
url: "https://example.com/blog/faster-builds",
type: "article",
siteName: "Example Blog",
locale: "en_US",
images: [
{
url: "https://example.com/images/faster-builds.jpg",
width: 1200,
height: 630,
alt: "A chart of build times dropping from 12 to 6 minutes",
},
],
},
twitter: {
card: "summary_large_image",
},
};
}
Nuxt in the page component
<script setup lang="ts">
useSeoMeta({
title: "How we cut our build time in half",
description: "What we changed in our CI pipeline, and what it saved.",
ogTitle: "How we cut our build time in half",
ogDescription: "What we changed in our CI pipeline, and what it saved.",
ogUrl: "https://example.com/blog/faster-builds",
ogType: "article",
ogSiteName: "Example Blog",
ogLocale: "en_US",
ogImage: "https://example.com/images/faster-builds.jpg",
ogImageWidth: 1200,
ogImageHeight: 630,
ogImageAlt: "A chart of build times dropping from 12 to 6 minutes",
twitterCard: "summary_large_image",
});
useHead({
link: [{ rel: "canonical", href: "https://example.com/blog/faster-builds" }],
});
</script>
React Router / Remix in the route module
// In a route module (React Router v7 framework mode or Remix v2).
export function meta() {
return [
{ title: "How we cut our build time in half" },
{ name: "description", content: "What we changed in our CI pipeline, and what it saved." },
{ tagName: "link", rel: "canonical", href: "https://example.com/blog/faster-builds" },
{ property: "og:title", content: "How we cut our build time in half" },
{ property: "og:description", content: "What we changed in our CI pipeline, and what it saved." },
{ property: "og:url", content: "https://example.com/blog/faster-builds" },
{ property: "og:type", content: "article" },
{ property: "og:site_name", content: "Example Blog" },
{ property: "og:locale", content: "en_US" },
{ property: "og:image", content: "https://example.com/images/faster-builds.jpg" },
{ property: "og:image:width", content: "1200" },
{ property: "og:image:height", content: "630" },
{ property: "og:image:alt", content: "A chart of build times dropping from 12 to 6 minutes" },
{ name: "twitter:card", content: "summary_large_image" },
];
}
Platforms cache previews. After a fix, ask Facebook to re-fetch the page in the Facebook Sharing Debugger (opens in a new tab), and then check your page again.