Fix: Missing og:description
Without an og:description, social platforms scrape your page to guess what it is about. Usually, they guess wrong. When a user pastes your link in Slack, Twitter, or iMessage, the platform looks for the og:description tag to generate the preview card. If it fails to find one, it falls back to the standard meta name="description". If that is also missing, it arbitrarily extracts the first paragraph of text it finds in your <body>.
The result is a social preview card that pitches your product with "Skip to main content", "Accept all cookies", or a disjointed navigation menu. Social preview text is your pitch. When you rely on automated extraction, your click-through rate drops.
Indxel's og-description rule flags this omission. It carries a severity weight of 4/100. While a missing Open Graph description will not penalize your Google search rankings, it directly degrades your acquisition funnel on social media, community forums, and direct messaging apps. Craft a social-specific description that drives clicks.
How do you detect a missing og:description?
Run npx indxel check in your terminal. The CLI scans your local routes and outputs a warning for every page missing the og:description tag.
$ npx indxel check
Scanning 47 routes...
/pricing
og-description: WARNING - Missing Open Graph description
missing-og-image: ERROR - No og:image found
/blog/nextjs-seo-guide
og-description: WARNING - Missing Open Graph description
✖ 2 issues found across 47 pages. Score: 96/100.The og-description rule is a warning, not a critical error. A missing Open Graph description does not break indexing, but it guarantees a poor social sharing experience. Fix this before pushing marketing pages or blog posts to production.
How do you fix a missing og:description?
Inject the og:description meta tag into your page head using your framework's metadata API. You must explicitly define the description property inside the Open Graph object.
Next.js App Router
Next.js 13+ handles Open Graph tags through the Metadata object. Developers frequently define the root description but forget the openGraph.description. While Next.js sometimes falls back to the root description automatically, explicitly defining the openGraph object guarantees the correct tag renders.
Bad: Missing Open Graph description
// app/layout.tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Indxel | Developer SEO Infrastructure',
description: 'Ship technical SEO with confidence.',
openGraph: {
title: 'Indxel | Developer SEO Infrastructure',
// Missing description here
url: 'https://indxel.com',
siteName: 'Indxel',
locale: 'en_US',
type: 'website',
},
}Good: Explicitly defined Open Graph description
// app/layout.tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Indxel | Developer SEO Infrastructure',
description: 'Ship technical SEO with confidence. Validate meta tags, catch broken links, and prevent indexing errors in CI.',
openGraph: {
title: 'Indxel | Developer SEO Infrastructure',
description: 'Ship technical SEO with confidence. Catch missing tags in CI before they hit production.',
url: 'https://indxel.com',
siteName: 'Indxel',
locale: 'en_US',
type: 'website',
},
}Notice the difference in the text. The standard description targets search engines with keywords. The Open Graph description is conversational, shorter, and optimized for a user scrolling a social feed.
For dynamic routes, use generateMetadata to pull the excerpt from your CMS or database.
// app/blog/[slug]/page.tsx
import { Metadata } from 'next'
import { getPost } from '@/lib/db'
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPost(params.slug)
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.socialExcerpt || post.excerpt,
type: 'article',
publishedTime: post.createdAt,
authors: [post.author.name],
},
}
}Next.js Pages Router
If you maintain a Pages Router application, inject the tag using next/head.
// pages/about.tsx
import Head from 'next/head'
export default function About() {
return (
<>
<Head>
<title>About Us</title>
<meta name="description" content="We build SEO tools for developers." />
<meta property="og:title" content="About Us" />
<meta property="og:description" content="We build SEO tools for developers. See our stack and team." />
</Head>
<main>
<h1>About Us</h1>
</main>
</>
)
}Plain HTML
For static sites or frameworks without a dedicated metadata API, add the <meta> tag directly to the <head>. Use property="og:description", not name="og:description".
<head>
<title>Indxel CLI</title>
<meta property="og:title" content="Indxel CLI" />
<meta property="og:description" content="Run SEO checks locally and in CI." />
</head>The Indxel SDK Approach
Duplicating titles and descriptions across the root metadata, Open Graph, and Twitter Card objects violates DRY principles. The Indxel SDK exposes a defineSEO helper that constructs all required tags from a single configuration object.
This is objectively superior to writing raw Next.js Metadata objects because it enforces strict type-checking on required fields. If you omit the description, TypeScript throws an error before you even run the CLI.
// lib/seo.ts
import { defineSEO } from '@indxel/sdk'
export const seo = defineSEO({
title: 'Indxel CLI',
description: 'Run SEO checks locally and in CI.',
url: 'https://indxel.com/cli',
// Automatically generates standard meta, og:description, and twitter:description
})
// app/page.tsx
import { seo } from '@/lib/seo'
export const metadata = seoHow do you prevent missing og:descriptions in CI?
Add npx indxel check --ci to your build pipeline. This fails the build if a developer merges a PR that omits the og:description on a new route.
For GitHub Actions, run the check after your build step but before deployment.
# .github/workflows/seo-check.yml
name: Indxel SEO Guard
on: [pull_request]
jobs:
validate-seo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm run build
- name: Run Indxel Check
run: npx indxel check --ci --diffAlways use the --diff flag in CI environments. This limits the scan to pages modified in the current pull request, reducing the check execution time to under 2 seconds.
If you use Vercel, integrate Indxel directly into the build command in your vercel.json or dashboard settings.
{
"buildCommand": "next build && npx indxel check --ci"
}What are common edge cases for og:description?
Developers routinely fix the missing tag but fail the rule by violating platform constraints.
Exceeding truncation limits
Facebook truncates Open Graph descriptions at approximately 300 characters. Twitter truncates at 200 characters. Slack and iMessage often truncate at 80-100 characters depending on the device viewport. If your og:description is 400 characters long, you are wasting bytes. Keep the description under 100 characters. Front-load the value proposition in the first 50 characters.
Duplicate descriptions on paginated routes
If you have a blog list at /blog, /blog?page=2, and /blog?page=3, do not use the exact same og:description for all three. While social platforms care less about duplication than Google search, duplicate descriptions indicate lazy dynamic routing. Append the page number to the description dynamically.
// Bad
description: "Read our latest developer articles."
// Good
description: `Read our latest developer articles. Page ${currentPage} of ${totalPages}.`Failing to strip HTML tags from CMS excerpts
When populating generateMetadata from a headless CMS (like Sanity or Contentful), developers often pass raw rich text or HTML into the description field. Open Graph tags do not parse HTML. If you pass <p>Welcome to <strong>Indxel</strong></p>, the literal HTML tags will render in the Slack preview. Always strip HTML tags before passing the string to the metadata object.
What related rules should you check?
When og-description fails, you likely have broader metadata issues. Run npx indxel check to validate these related rules:
missing-og-title: Fails ifog:titleis absent.missing-og-image: Fails if the route lacks a social preview image.missing-meta-description: Fails if the standard search engine description is missing.
Frequently Asked Questions
How long should og:description be?
Keep og:description under 100 characters. Twitter truncates at about 200 characters, Facebook at about 300, but messaging apps like Slack show much less. Shorter is always better for social previews.
Can I just use my standard meta description for og:description?
Yes, but it is sub-optimal. Search meta descriptions are written to match search intent and often include target keywords. Open Graph descriptions are written to capture attention in a fast-scrolling social feed. Write them like ad copy.
Why does my og:description not update on Twitter or LinkedIn?
Social platforms aggressively cache Open Graph tags based on the URL. Updating the tag in your code will not immediately change the preview. You must paste your URL into the LinkedIn Post Inspector or use the Twitter Card Validator to force the platforms to flush their cache and re-scrape your page.
Does og:description affect Google search rankings?
No. Open Graph tags are strictly consumed by social media networks, messaging platforms, and enterprise tools (like Slack and Notion). Google does not use og:description for search indexing or ranking algorithms.
Does Indxel check og:description behind authentication?
Yes. If you pass authentication headers via npx indxel check --headers "Authorization: Bearer <token>", Indxel will validate Open Graph descriptions on protected routes. This is critical for staging environments or gated documentation.
Frequently asked questions
How long should og:description be?
Under 100 characters for most platforms. Twitter truncates at about 200, Facebook at about 300, but Slack and messaging apps show much less. Shorter is better.