All fixes
critical
Rule: description-presentWeight: 5/100

Fix: Missing meta description

When you skip the meta description, Google pulls a random text snippet from your page to display in search results. It is usually the wrong paragraph. Search engines will grab a navigation menu item, a cookie banner, or an out-of-context sentence. Indxel's description-present rule (weight: 5/100) flags this as a critical error because a missing description directly degrades your click-through rate (CTR).

Think of the meta description as ad copy for your organic search listing. If you let a search engine auto-generate it, you lose control over your value proposition. Pages without explicit descriptions see lower engagement because users cannot quickly determine if the page answers their intent. The auto-generated snippet rarely communicates why someone should click your link over the competitor directly below you. This rule should never ship to production failing.

How do you detect missing meta descriptions?

You detect missing meta descriptions by running npx indxel check against your local environment or production URL, which flags pages failing the description-present rule.

The CLI outputs warnings in the same format as ESLint — one line per issue, with the file path and rule ID.

$ npx indxel check http://localhost:3000
 
❌ 3 critical errors found
 
/about
  Line 1: Missing meta description. [description-present]
 
/products/acme-widget
  Line 1: Missing meta description. [description-present]
 
/blog/hello-world
  Line 1: Missing meta description. [description-present]
 
Score: 91/100
✖ Run failed.

The description-present rule is a critical failure. Indxel assigns it a weight of 5/100. If this rule fails, your overall SEO score drops significantly, and strict CI checks will block the build.

How to fix missing meta descriptions across frameworks?

You fix this by exporting a metadata object in Next.js App Router, using the <Head> component in Pages Router, or injecting a standard <meta name="description"> tag in raw HTML.

Write 120-160 characters that describe what the page offers and why someone should click.

Next.js App Router

Next.js handles metadata natively via the metadata export in layout.tsx or page.tsx. A common mistake is exporting a title but omitting the description.

// app/pricing/page.tsx
import type { Metadata } from 'next';
 
// ❌ BAD: Title present but no description
export const metadata: Metadata = {
  title: 'Pricing | Acme Corp',
};
 
export default function PricingPage() {
  return <h1>Pricing</h1>;
}

Add the description string to the exported object.

// app/pricing/page.tsx
import type { Metadata } from 'next';
 
// ✅ GOOD: Clear, benefit-driven description (120-160 characters)
export const metadata: Metadata = {
  title: 'Pricing | Acme Corp',
  description: 'Compare Acme Corp pricing plans. Start for free, upgrade when you need advanced analytics, custom domains, and SSO. No credit card required.',
};
 
export default function PricingPage() {
  return <h1>Pricing</h1>;
}

Next.js Pages Router

If you maintain legacy Pages Router code, inject the tag using next/head.

// pages/pricing.tsx
import Head from 'next/head';
 
export default function Pricing() {
  return (
    <>
      <Head>
        <title>Pricing | Acme Corp</title>
        {/* ✅ GOOD: Explicit meta tag */}
        <meta name="description" content="Compare Acme Corp pricing plans. Start for free, upgrade when you need advanced analytics, custom domains, and SSO." />
      </Head>
      <h1>Pricing</h1>
    </>
  );
}

Indxel SDK Approach

If you use Indxel's SDK to standardize metadata across your application, use the createMetadata helper. This is the recommended approach. It enforces presence and length limits at compile time, failing your TypeScript build before Indxel even runs.

// app/layout.tsx
import { createMetadata } from '@indxel/seo';
 
// ✅ GOOD: Indxel SDK throws a TS error if description is omitted
export const metadata = createMetadata({
  title: 'Acme Corp',
  description: 'The developer-first platform for shipping faster.',
  path: '/',
});

Plain HTML

For static HTML sites, place the tag inside the <head> block.

<!-- ✅ GOOD: Standard HTML implementation -->
<head>
  <title>Pricing | Acme Corp</title>
  <meta name="description" content="Compare Acme Corp pricing plans. Start for free, upgrade when you need advanced analytics, custom domains, and SSO.">
</head>

How do you prevent missing descriptions in CI?

Prevent missing descriptions by adding npx indxel check --ci to your build pipeline to automatically fail pull requests that omit the description tag.

You cannot rely on manual code reviews to catch missing metadata. Automate the guard. Adding Indxel to your CI pipeline adds roughly 2 seconds to your build and guarantees 100% of your pages ship with valid descriptions.

GitHub Actions

Add a validation step before your deployment job in your workflow file.

# .github/workflows/seo-check.yml
name: SEO Guard
on: [push, pull_request]
 
jobs:
  validate:
    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 SEO Check
        run: npx indxel check .next/server/app --ci --strict

Vercel Build Command

You can block bad deployments directly in Vercel by modifying your build command. If indxel check fails, the build fails, and the broken code never overwrites production.

# Vercel Project Settings > Build & Development Settings > Build Command
npm run build && npx indxel check --ci

Use the --diff flag in PR workflows. Running npx indxel check --ci --diff only checks pages modified in the current branch, reducing CI time from seconds to milliseconds.

What are the edge cases for dynamic meta descriptions?

Dynamic routes, paginated lists, and user-generated content often trigger the description-present error because developers forget to fetch or generate description text alongside the main payload.

Dynamic Routes (Next.js)

When rendering blog posts or product pages dynamically, you must use generateMetadata(). The description must come from your database or CMS. If a CMS entry lacks a custom description field, fall back to a truncated version of the body content.

// 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,
    // Fallback to the first 150 characters of the post body if excerpt is null
    description: post.excerpt || post.body.substring(0, 150).trim() + '...',
  };
}

Pagination Duplication

Every page needs a description, but every description must be unique. Duplicating the same description across /blog?page=1 and /blog?page=2 dilutes your SEO and triggers duplicate metadata warnings in Google Search Console. Append the page number to the description string.

const description = currentPage > 1
  ? `Read our latest articles on web development. Page ${currentPage} of ${totalPages}.`
  : `Read our latest articles on web development, React, and serverless architecture.`;

Special Characters

Quotes (" and ') inside raw HTML descriptions will break the tag if not properly escaped. React and Next.js handle this automatically. If you render raw HTML strings in a custom server (like Express or Go), you must escape the output manually to prevent breaking the DOM structure.

Which related Indxel rules should you check?

When fixing description-present, you should also validate meta-description-too-long, missing-title, and missing-og-description to ensure your entire metadata stack is compliant.

  • meta-description-too-long: Adding a description is step one. Keeping it between 120-160 characters is step two. Google truncates anything longer, rendering the extra bytes useless.
  • missing-title: A description without a title is an incomplete search snippet. Titles carry heavier ranking weight than descriptions.
  • missing-og-description: While the standard meta description handles search engines, the og:description handles social shares (Twitter, Slack, LinkedIn). If og:description is missing, social platforms often fall back to the standard meta description, but explicitly defining both is the safer implementation.

Frequently Asked Questions

Does Google always use my meta description?

No. Google rewrites your description roughly 60% of the time based on the user's search query. However, providing a highly relevant, well-written description significantly increases the probability that Google uses your exact text.

What should a meta description include?

A concise summary of the page content, your primary keyword naturally integrated, and a clear reason to click. Treat it as a 150-character advertisement for your page. Avoid keyword stuffing; write for human readability.

Can I use the same meta description on every page?

No. Duplicate descriptions trigger separate SEO penalties. If you cannot write a unique description for a specific page, it is technically better to leave it blank and let Google extract a snippet than to duplicate a generic description across 1,000 pages.

Does the meta description affect search rankings directly?

No. Google confirmed in 2009 that meta descriptions are not a direct ranking factor. However, they directly impact Click-Through Rate (CTR), and CTR is a behavioral signal that heavily influences how your page performs in search results over time.

Frequently asked questions

Does Google always use my meta description?

No. Google sometimes rewrites your description based on the search query. But having a well-written description increases the chance Google uses yours. It also controls what appears when your page is shared.

What should a meta description include?

A concise summary of the page content, your primary keyword naturally included, and a reason to click. Think of it as ad copy for your search listing. 120-160 characters is the sweet spot.

Catch this before it ships

$npx indxel check --ci
Get startedBrowse all fixes
Indxel

SEO validation that runs in your terminal and blocks bad deploys.

GitHubnpm

Product

  • Documentation
  • Pricing
  • Plus Plan
  • CI/CD Guard
  • Indexation
  • Free Tools
  • Blog

Comparisons

  • vs Semrush
  • vs Ahrefs
  • vs Moz
  • vs Screaming Frog
  • All comparisons

Integrations

  • Vercel
  • GitHub Actions
  • Netlify
  • Docker
  • All integrations

Resources

  • Frameworks & use cases
  • Next.js
  • For freelancers
  • For agencies
  • SEO Glossary

Built with care. MIT Licensed.

PrivacyTermsLegalContact