agentspeed.
← all fixes
Issue remediation

Weak title and meta description

Your <title> and meta description are missing, generic, or duplicated, so agents can't tell what each page is about at a glance.

failed checkmarkup.titlemarkup.meta_descriptionmarkup.canonical
What this means

The <title> and <meta name="description"> are the two highest-density signals a page emits. They sit in <head>, ship in the initial HTML, and are read by every agent on its first pass, long before the body content is parsed. Weak metadata means: the title is generic ("Home" / "Untitled Page"), the description is missing or auto-generated boilerplate, or every page on the site uses the same title-and-description.

Why it matters for AI agents

Agents use the title to label the page in answers and citations. They use the description as the snippet under the title. If the title says "Home" and the description is empty, the agent has nothing distinctive to display, and often will not cite the page at all because there's no way to tell users what they'd be clicking on. Distinct, accurate, page-specific titles and descriptions are 30 minutes of work that pay off across every agent surface.

Business impact

Weak metadata costs you in three places at once: agent citations (which use the title verbatim), social shares (Open Graph falls back to <title> when og:title is missing), and traditional SEO (Google still uses <title> as a ranking signal). Sites with templated, page-specific titles see meaningfully higher click-through and citation rates than sites with generic titles. There is no downside.

How to check manually

Open view-source on five pages from different sections of your site (homepage, a product, a blog post, an about page, a category page). For each: confirm <title> is unique and descriptive, <meta name="description"> exists and is 120–160 characters of human-readable copy, and <link rel="canonical"> points to the canonical URL. If three of the five fail, you have a metadata problem.

The exact fix

Generate a unique <title> and <meta name="description"> for every page. Pattern: "<Page-specific phrase> | <Site name>" for the title; a 120–160-char sentence describing the page contents for the description. Add <link rel="canonical"> to every page so agents know which URL is authoritative when query strings or duplicate paths exist.

Copy-paste snippet
Reference snippethtmlproduct-page.html
<head>
  <title>10" Cast-Iron Skillet, pre-seasoned — Acme</title>
  <meta name="description"
        content="Hand-poured cast-iron skillet, pre-seasoned with flax oil, made in Ohio. Lifetime warranty, free shipping over $75. $79.">
  <link rel="canonical" href="https://acme.com/products/skillet-10">

  <!-- Open Graph for social sharing -->
  <meta property="og:title" content="10\" Cast-Iron Skillet — Acme">
  <meta property="og:description" content="Pre-seasoned cast-iron skillet, made in Ohio. $79.">
  <meta property="og:type" content="product">
  <meta property="og:url" content="https://acme.com/products/skillet-10">
</head>
Platform-specific implementations

The reference snippet above is platform-agnostic. Below are the concrete steps for the four most common stacks plus a generic fallback for any other host.

Next.js

Next.js App Router has first-class metadata via the `metadata` export (static) or `generateMetadata` (dynamic, async). Export one or the other from each page.tsx. The metadata API generates <title>, <meta>, <link rel="canonical">, and Open Graph tags from a single object, with no manual <head> manipulation. For dynamic routes, fetch the data inside generateMetadata and return per-page values.

Next.jstsxapp/products/[slug]/page.tsx
import type { Metadata } from 'next';
import { getProduct } from '@/lib/products';

export async function generateMetadata({
  params,
}: {
  params: Promise<{ slug: string }>;
}): Promise<Metadata> {
  const { slug } = await params;
  const product = await getProduct(slug);
  return {
    title: `${product.name} — Acme`,
    description: product.shortDescription,
    alternates: { canonical: `/products/${slug}` },
    openGraph: {
      title: `${product.name} — Acme`,
      description: product.shortDescription,
      type: 'website',
      url: `https://acme.com/products/${slug}`,
    },
  };
}

export default async function ProductPage(/* … */) {
  /* … */
}

WordPress

WordPress core gives every post and page a Title field but does not handle meta description natively. Yoast SEO and Rank Math both add per-post Title + Description editors and emit the correct <head> tags. Without a plugin, hook into wp_head from your theme to echo the description from a custom field; remember to use the_title() and post excerpt as fallbacks so unauthored pages still get something distinctive.

WordPressphpfunctions.php
add_action( 'wp_head', function () {
  if ( is_singular() ) {
    $description = get_post_meta( get_the_ID(), 'meta_description', true );
    if ( ! $description ) {
      $description = wp_trim_words( get_the_excerpt(), 30, '…' );
    }
    if ( $description ) {
      printf(
        '<meta name="description" content="%s">' . "\n",
        esc_attr( $description )
      );
    }
    printf(
      '<link rel="canonical" href="%s">' . "\n",
      esc_url( get_permalink() )
    );
  }
}, 5 );

Shopify

Shopify gives every product, collection, page, and blog post a "Search engine listing" preview where you can edit the meta title and description. The default theme Liquid templates emit them via {{ page_title }} and {{ page_description }}. The fix is procedural: open Admin → Products / Collections / Pages and fill in the listing field for every URL. For bulk editing, use the bulk editor or a CSV import. Set canonical URLs in your theme.liquid using {{ canonical_url }}.

Shopifyliquidlayout/theme.liquid
<head>
  <title>
    {{ page_title }}
    {%- if current_tags %} — tagged "{{ current_tags | join: ', ' }}"{%- endif -%}
    {%- unless page_title contains shop.name %} — {{ shop.name }}{%- endunless -%}
  </title>
  {%- if page_description -%}
    <meta name="description" content="{{ page_description | escape }}">
  {%- endif -%}
  <link rel="canonical" href="{{ canonical_url }}">
</head>

Webflow

Webflow has per-page title and description fields under Page settings → SEO settings. For static pages, fill them in by hand. For CMS pages, bind them to Collection fields (e.g. {Article Title} for the title, {Article Excerpt} for the description) so every published item gets distinct metadata automatically. Canonical URLs are auto-generated by Webflow but can be overridden per page if you syndicate content.

WebflowtxtCMS template → Page settings → SEO
Title tag: {{ Article Title }} — Acme
Meta description: {{ Article Excerpt }}
Canonical URL: (leave default; Webflow uses the published URL)

Static HTML / any stack

Hand-author <title>, <meta name="description">, and <link rel="canonical"> in every HTML file's <head>. For static-site generators, set them via front-matter and a layout template that interpolates the values. Don't share a single layout that hard-codes the title; every page needs its own.

Static HTML / any stackmdcontent/blog/seasoning-guide.md
---
title: How to season cast iron — a guide
description: A step-by-step seasoning guide for new and restored cast-iron pans, with photos and oil recommendations.
canonical: https://acme.com/blog/seasoning-guide
---

# How to season cast iron

(Body copy here — interpolated into the layout below.)
Common mistakes
How to re-test

View source on three representative pages and confirm <title>, <meta name="description">, and <link rel="canonical"> are present, distinct, and accurate. Run a fresh AgentSpeed scan, and the title, meta-description, and canonical checks should all flip to pass. Submit the sitemap to Google Search Console; the "duplicate without canonical" warnings should clear within a few weeks.

FAQ
How long should the title be?

Aim for 50–60 characters. Longer titles get truncated in agent citations and search results; shorter titles waste signal. The page-specific phrase comes first, then a separator, then the site name.

Does the meta description still matter for SEO?

Google rewrites the description for ~70% of queries (it picks a snippet from the body that better matches the query). But agents and social shares use the meta description verbatim, so writing a good one is still high-leverage.

What about Open Graph tags, do agents use them?

Some do (LinkedIn-driven agents, social-aware crawlers). Open Graph is cheap to add once you have a good <title> and <meta name="description">, since most fields just mirror those two. Add og:title, og:description, og:image, og:type as a baseline.

Verify on your site
Run a scan

Free scan, no signup. The score page is permanent and citable, so you can link it from your team's remediation ticket alongside this guide for “Weak title and meta description”.

Run a free scan →See all fixes →