Titles & Meta Tags
The <head> of your document carries the highest signal-per-byte in SEO. The title tag remains one of the strongest on-page ranking factors, and together with the meta description it is your SERP listing - your ad copy in the organic results.
Title tags#
The rules that matter#
- One title per page, unique across the site. Duplicate titles tell engines your pages are interchangeable.
- Front-load the primary keyword - naturally, not robotically. Relevance scoring and scanning users both weight the start.
- ~50–60 characters. Longer titles get truncated or rewritten. Google rewrites titles it considers poor; clear, accurate titles get rewritten less.
- Make it a promise the page keeps. Click-throughs followed by instant returns (pogo-sticking) tell engines the promise was false.
How to Fix Soft 404 Errors in Next.js (5 Causes) ← how-to + specificity
Core Web Vitals: A Field Guide for React Developers ← keyword + audience
Ahrefs vs Semrush: We Tested Both for 6 Months ← comparison + experience
robots.txt Generator - Free, No Signup ← tool + objection removalSetting titles in Next.js#
import type { Metadata } from "next";
export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>;
}): Promise<Metadata> {
const { slug } = await params;
const post = await getPost(slug);
return {
title: post.title, // template in layout adds the site suffix
description: post.excerpt,
};
}Use the title.template pattern in your root layout ("%s · YourBrand") so every page gets consistent branding without repetition.
Meta descriptions#
Descriptions are not a ranking factor, but they heavily influence click-through rate - which makes them one of the cheapest wins in SEO. Rules:
- ~150–160 characters, unique per page
- Include the primary keyword (it gets bolded in the SERP when it matches the query)
- Write it as ad copy: state the benefit, create a reason to click
- Expect Google to override it with page text when it thinks a passage matches the query better - that's fine
Canonical tags#
The canonical tag declares the preferred URL when content is reachable at multiple addresses (tracking parameters, www/non-www, http/https, print versions):
export async function generateMetadata({ params }): Promise<Metadata> {
const { id } = await params;
return {
alternates: {
canonical: `https://example.com/products/${id}`,
},
};
}Canonicals are a hint, not a directive - engines can ignore them if signals disagree. Deep coverage in Crawling & Indexing.
Robots meta#
Controls indexing and snippet behavior per page:
<meta name="robots" content="noindex, follow" />| Value | Effect |
|---|---|
noindex | Keep out of search results (page must be crawlable for this to be seen) |
nofollow | Don't follow this page's links |
max-snippet:N | Limit text snippet length (relevant for AI Overviews/licensing) |
nosnippet | No snippet at all - usually a traffic killer, use deliberately |
Open Graph & social cards#
OG tags don't affect rankings, but they control how links render in social feeds, chat apps - and increasingly in AI chat interfaces:
export const metadata: Metadata = {
openGraph: {
title: "seo101 - SEO, AEO & GEO from zero to hero",
description: "The complete free curriculum for modern search.",
type: "website",
images: ["/og.png"], // 1200×630
},
twitter: { card: "summary_large_image" },
};Next: Content Optimization - structuring the body of the page itself.
