Every SEO audit tool flags it: "37 pages missing meta description." And every developer who's looked at actual search results has noticed that the snippet shown often isn't the meta description at all. Search engines frequently rewrite it, pulling a sentence from the page that better matches the query.
So which is it? Is the meta description a required field, or a vestigial tag we keep filling in out of habit?
Let's lay out both sides honestly, then I'll tell you where we land, and I'd like to hear where you land.
The case against bothering
1. It's not a ranking factor. Search engines have said for years that the meta description doesn't directly affect rankings. Nobody serious disputes this.
2. It gets rewritten a lot. For many queries, especially long or specific ones, the search engine picks text from the page body because it matches the query better than your summary does. Studies by various SEO tool vendors over the years have reported rewrite rates ranging from "a lot" to "most of the time", depending on method. Even taking the lower estimates, a large share of your carefully written descriptions never appears.
3. Bad descriptions are worse than none. A templated description repeated across 500 pages ("Welcome to Acme, the best place for...") is more likely to be ignored and tells nobody anything. Leaving it blank at least lets the search engine choose something relevant.
4. Developer time is finite. On a site with 10,000 product or docs pages, writing a unique, good description for each is a real cost. That time could fix broken internal links or slow templates instead.
The case for writing them
1. Rewritten "often" isn't "always". For short, navigational and head-term queries, which often bring the most traffic to key pages, your description is frequently used as-is. Those are exactly the pages where a good pitch matters.
2. It's used beyond search. Many social platforms, chat apps and link previewers fall back to the meta description when Open Graph tags are missing. Some internal site search tools use it too. A missing description can mean an ugly or empty preview when someone shares the link in Slack.
3. It's a forcing function. If you can't summarise a page in 150 characters, that's a signal about the page. Writing the description is a cheap content review.
4. It's a click-through lever, not a ranking lever. Ranking gets you on the page; the snippet gets you the click. Even a modest CTR improvement on your top pages is worth an hour of writing.
Where we land
Our position: write them for pages that matter, generate sensible ones for the rest, and never duplicate them.
In practice:
- Top pages by impressions (home, pricing, key landing pages, top articles): hand-written, specific, and checked against what actually shows in results.
- Templated pages (products, docs, locations): generate from real page data, such as the product's key attribute, price range or the doc page's first sentence. Unique per page, even if not beautiful.
- Thin or low-value pages: fix or remove the page instead of polishing its description.
- Never: the same description on many pages. That's the one pattern that's clearly worse than leaving it blank.
A tiny audit to see where you stand
Before arguing in the abstract, check your own build output. This script walks a directory of rendered HTML (for example, a static site's dist/ or public/ folder) and flags missing, very long and duplicated descriptions:
import sys, pathlib, re from collections import defaultdict from html.parser import HTMLParser class Meta(HTMLParser): def __init__(self): super().__init__(); self.desc = None def handle_starttag(self, tag, attrs): a = dict(attrs) if tag == "meta" and (a.get("name") or "").lower() == "description": self.desc = (a.get("content") or "").strip() root = pathlib.Path(sys.argv[1]) seen = defaultdict(list) for f in sorted(root.rglob("*.html")): p = Meta(); p.feed(f.read_text(errors="ignore")) d = p.desc if not d: print(f"MISSING {f.relative_to(root)}") continue seen[d].append(str(f.relative_to(root))) if len(d) > 160: print(f"LONG({len(d)}) {f.relative_to(root)}") for d, files in seen.items(): if len(files) > 1: print(f"DUPLICATE {', '.join(files)}: {d[:50]!r}") Running it on a tiny four-page test folder:
$ python3 metadesc.py site MISSING c.html LONG(181) d.html DUPLICATE a.html, b.html: 'Simple plans for teams of every size.' The 160-character threshold is a rough guide, not a rule; snippets are truncated by pixel width, not character count. The duplicate check is the one I'd take most seriously.
For a framework that renders on the server, point the script at a folder of pages fetched with wget --mirror or your crawler of choice instead.
Generating decent descriptions for templated pages
If you go the "generate for the long tail" route, keep it simple and data-driven. A sketch for a product template:
function productDescription(p) { const parts = [ `${p.name} by ${p.brand}`, p.keyFeature, p.inStock ? `In stock from ${p.priceFormatted}` : "Currently out of stock", ].filter(Boolean); const text = parts.join(". ") + "."; return text.length > 155 ? text.slice(0, 152).trimEnd() + "..." : text; } It won't win awards, but it's unique, accurate, and more useful than a site-wide slogan. And because it's built from data, it stays correct when the price or stock changes.
Questions I genuinely don't have a settled answer to
- Should docs pages use the first paragraph as the description? It's usually the best summary, but then the snippet repeats what the page says first anyway.
- Is it worth A/B testing descriptions? Search CTR is noisy and slow to measure. Some teams swear by it; others think it's mostly reading tea leaves.
- What about AI-generated descriptions at scale? Cheap and unique, but they often drift towards generic phrasing that sounds like every other site.
If you want an automated pass that catches missing and duplicate descriptions alongside the rest of your on-page basics, seotto.com audits that on a schedule. But the argument itself is about what's worth your time, and that's a judgement call.
Related reading
- Find duplicate and missing title tags with a Python crawl script
- There is no duplicate content penalty (but duplicate content still costs you)
- Breadcrumbs are the most underrated SEO component in your design system
- Image SEO: 7 things I'd do differently on the next big site (starting with hashed filenames)
- What your 500s, 503s and 429s tell search crawlers (and how to take a site down for maintenance without hurting SEO)
So, where are you: hand-write every one, generate them, or leave them blank and let search engines decide? Make your case in the comments.


