Fix: Meta description too long
Google truncates meta descriptions over 160 characters. Anything past that limit gets replaced by an ellipsis (...), instantly killing your call-to-action or critical value proposition. Search engines use this snippet as your organic ad copy. If the user cannot read the benefit, they will not click the link. A 248-character description that gets cut at 160 characters drops your click-through rate, rendering the extra text entirely useless.
Indxel's description-length rule (weight: 8/100) mathematically evaluates your rendered <meta name="description"> tags. It enforces the search snippet window. Descriptions between 161 and 200 characters trigger a warning. Descriptions exceeding 200 characters trigger a hard error.
How do you detect long meta descriptions?
Run the Indxel CLI against your local development server or production URL. The CLI parses the DOM, extracts the content attribute from the meta description tag, and calculates the exact character length.
npx indxel check http://localhost:3000If a description exceeds the limit, the CLI outputs a specific warning or error tied to the description-length rule ID:
✖ 1 issue found across 1 page
/blog/how-to-configure-caching
Line 8:4 warning Meta description is 248 characters long. Max recommended is 160. description-lengthIndxel enforces two boundaries for length. 161–200 characters returns a WARNING (exit code 0). 201+ characters returns an ERROR (exit code 1). This distinction allows you to fail CI builds for massive regressions while letting minor overflows pass.
How do you fix description-length in your code?
Trim the text to fit within the 120-160 character sweet spot. Cut filler words. Lead with the benefit. Place your call-to-action before the 120-character mark to survive mobile truncation.
Here is a 248-character description that fails the check: “Welcome to our platform where we provide the best developer tools for SEO infrastructure so you can build faster, scale infinitely, and ensure that all your pages rank number one on Google search results without having to learn anything about marketing.”
Here is the 138-character fixed version that passes: “Indxel provides developer-first SEO infrastructure. Validate metadata, catch regressions in CI, and ship optimized pages from the terminal.”
Next.js App Router
In the Next.js App Router, you define descriptions via the Metadata object. Update the description key in your layout or page file.
Bad (Fails check):
// app/page.tsx
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Indxel | SEO Infrastructure',
// 248 characters - triggers description-length warning
description: 'Welcome to our platform where we provide the best developer tools for SEO infrastructure so you can build faster, scale infinitely, and ensure that all your pages rank number one on Google search results without having to learn anything about marketing.',
};
export default function Page() {
return <main>...</main>;
}Good (Passes check):
// app/page.tsx
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Indxel | SEO Infrastructure',
// 138 characters - passes perfectly
description: 'Indxel provides developer-first SEO infrastructure. Validate metadata, catch regressions in CI, and ship optimized pages from the terminal.',
};
export default function Page() {
return <main>...</main>;
}Next.js Pages Router
If you are maintaining a Next.js Pages Router application, the description lives inside the next/head component.
// pages/index.tsx
import Head from 'next/head';
export default function Home() {
return (
<>
<Head>
<title>Indxel | SEO Infrastructure</title>
<meta
name="description"
content="Indxel provides developer-first SEO infrastructure. Validate metadata, catch regressions in CI, and ship optimized pages from the terminal."
/>
</Head>
<main>...</main>
</>
);
}Indxel SDK
If you use the Indxel SDK to manage metadata across a large Next.js application, the defineSEO function provides inline TypeScript validation for character limits.
import { defineSEO } from '@indxel/sdk';
export const metadata = defineSEO({
title: 'Indxel | SEO Infrastructure',
description: 'Indxel provides developer-first SEO infrastructure. Validate metadata, catch regressions in CI, and ship optimized pages from the terminal.',
});Plain HTML
For static site generators or raw HTML files, locate the <head> block and update the <meta> tag directly.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Indxel | SEO Infrastructure</title>
<meta name="description" content="Indxel provides developer-first SEO infrastructure. Validate metadata, catch regressions in CI, and ship optimized pages from the terminal.">
</head>
<body>
...
</body>
</html>How do you prevent long descriptions in CI/CD?
Catch bloated metadata before it merges to the main branch. Integrate the Indxel CLI into your continuous integration pipeline.
Run npx indxel check --ci in your build command. By default, the CLI returns exit code 1 if it encounters any rule flagged as an ERROR (like a 201+ character description), automatically failing the build.
Vercel Build Command
The fastest way to guard production is to modify your Vercel build command in package.json. The build will fail if indxel check detects critical errors.
{
"scripts": {
"dev": "next dev",
"build": "indxel check --ci && next build",
"start": "next start"
}
}GitHub Actions
For more granular control, run Indxel against a preview deployment URL in GitHub Actions. Use the --diff flag to only check pages modified in the current pull request.
name: SEO Guard
on: [pull_request]
jobs:
indxel-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Wait for Vercel Preview
uses: patrickedqvist/wait-for-vercel-preview@v1.3.1
id: vercel
with:
token: ${{ secrets.GITHUB_TOKEN }}
max_timeout: 300
- name: Run Indxel Check
run: npx indxel check ${{ steps.vercel.outputs.url }} --ci --diffIf you want to enforce strict 160-character limits and fail the build on warnings (not just errors), pass the --strict flag: npx indxel check --ci --strict. This treats all warnings as exit code 1.
What are the edge cases for dynamic descriptions?
Hardcoded descriptions rarely fail this check. The description-length rule almost always catches dynamic routes pulling data from a CMS, database, or markdown file.
When you generate metadata dynamically, developers often use the first 160 characters of the page content. A naive .substring(0, 160) is dangerous. It cuts words in half, leaves dangling punctuation, or breaks HTML entities.
Bad dynamic truncation:
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const post = await db.post.findUnique({ where: { slug: params.slug } });
return {
title: post.title,
// Naive slice. Results in: "This article explains how to configure..."
description: post.content.substring(0, 160) + '...',
};
}If character 160 lands in the middle of an HTML entity like &, the browser renders broken text. If it lands in the middle of a word, you get unprofessional output like infrastructure for dev....
Good dynamic truncation: Use a utility function that respects word boundaries and strips markdown/HTML before counting characters.
function generateSafeDescription(htmlContent: string, maxLength = 155): string {
// 1. Strip HTML tags
const plainText = htmlContent.replace(/<[^>]+>/g, '');
// 2. Return if already short enough
if (plainText.length <= maxLength) return plainText;
// 3. Slice to max length
const truncated = plainText.substring(0, maxLength);
// 4. Find the last space to avoid cutting words in half
const lastSpaceIndex = truncated.lastIndexOf(' ');
// 5. Append ellipsis
return `${truncated.substring(0, lastSpaceIndex)}...`;
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const post = await getPost(params.slug);
return {
title: post.title,
description: generateSafeDescription(post.content),
};
}Which related rules should you check?
Fixing description-length often reveals other metadata issues. Look out for these related Indxel rules:
missing-meta-description: Triggers when the tag is completely absent.title-too-long: Triggers when the<title>tag exceeds 60 characters, resulting in similar truncation in search results.duplicate-meta-description: Triggers when multiple pages share the exact same 120-160 character string, a common regression when applying template-wide fixes.
FAQ: Meta Description Length
What is the ideal meta description length?
Between 120 and 160 characters. Descriptions between 70-119 or 161-200 characters trigger a warning in Indxel. Below 70 or above 200 is flagged as an error. Staying within 120-160 guarantees your entire message renders across the vast majority of search result pages.
Are mobile truncation limits different from desktop?
Yes. Mobile search results often truncate descriptions around 120 characters, while desktop displays up to 160 characters. Front-load your core value proposition and primary call-to-action into the first 120 characters to ensure mobile users see the critical information before the ellipsis.
Should I stuff keywords in my description?
No. Google bolds matching keywords in the snippet, but keyword stuffing makes your description unreadable. Include your primary keyword once, naturally. A natural, readable description with a clear benefit drives a higher click-through rate than a string of comma-separated search terms.
Does Google always use my meta description?
No. Google rewrites the snippet roughly 60% of the time based on the user's search query, often pulling context directly from the page body. However, providing a concise, accurate description under 160 characters significantly increases the probability that Google uses your authored snippet instead of an auto-generated one.
Frequently asked questions
What is the ideal meta description length?
120-160 characters. Descriptions between 70-119 or 161-200 characters trigger a warning in Indxel. Below 70 or above 200 is flagged as an error.
Should I stuff keywords in my description?
No. Google bolds matching keywords in the snippet, but keyword stuffing makes your description unreadable. Include your primary keyword once, naturally.