Next.js Metadata: Titles, Descriptions, OG, and Canonicals

Metadata is the fastest way to improve how your Next.js pages appear in search results and social previews. This guide shows a clean setup for titles, descriptions, Open Graph, Twitter cards, canonicals, and per-route metadata (App Router).

By Olamisan~12 min readNext.js

What “good metadata” means

A good metadata setup should do 5 things:

  • Unique title per page, following a consistent pattern.
  • Meaningful description that matches the page content.
  • Correct canonical URL (absolute, preferred host/protocol).
  • Good social previews (Open Graph + Twitter card).
  • Safe indexing rules (no accidental indexing for staging).

Related: Technical SEO basicsRobots + sitemap setup

Set solid defaults in app/layout

Use defaults so every route gets “good enough” metadata, then override per page. In App Router, define a metadata export in app/layout.tsx.

Example default metadata (App Router)

// app/layout.tsx
import type { Metadata } from "next";

const siteUrl = "https://blog.olamisan.com";

export const metadata: Metadata = {
  metadataBase: new URL(siteUrl),
  title: {
    default: "Olamisan — Practical Developer Notes",
    template: "%s — Olamisan"
  },
  description:
    "Practical notes and tutorials about web performance, technical SEO, automation, and developer tools.",
  alternates: {
    canonical: "/"
  },
  openGraph: {
    type: "website",
    url: siteUrl,
    siteName: "Olamisan",
    title: "Olamisan — Practical Developer Notes",
    description:
      "Practical notes and tutorials about web performance, technical SEO, automation, and developer tools.",
    images: [
      {
        url: "/assets/og-cover.png",
        width: 1200,
        height: 630,
        alt: "Olamisan blog cover"
      }
    ]
  },
  twitter: {
    card: "summary_large_image",
    title: "Olamisan — Practical Developer Notes",
    description:
      "Practical notes and tutorials about web performance, technical SEO, automation, and developer tools.",
    images: ["/assets/og-cover.png"]
  }
};

Tip: metadataBase makes relative OG image paths resolve correctly.

Titles: patterns that scale

Titles should be descriptive, human, and consistent. A scalable pattern:

  • Post pages: “Exact Topic + Outcome (Optional) — Brand”
  • Category pages: “Category Name: What you’ll learn — Brand”
  • Homepage: “Brand — Primary topics”

Good title examples

  • “Core Web Vitals Quick Wins: LCP, CLS, and INP Improvements — Olamisan”
  • “Technical SEO Basics for Developers: What to Fix First — Olamisan”
  • “Next.js Metadata: Titles, OG, and Canonicals — Olamisan”

Descriptions: consistent and human

Meta descriptions don’t directly change rankings, but they strongly influence click-through. A simple formula: what it is + who it’s for + what you’ll get.

  • Keep it close to what the page actually delivers.
  • Avoid keyword stuffing.
  • Use consistent voice across pages.

Open Graph and Twitter cards

Open Graph tags improve previews on social platforms and messengers. Even though it’s not a direct ranking factor, it helps your content get clicked and shared.

Minimum social preview setup

  • One consistent OG image style (1200×630 recommended).
  • Clear title and description that match the page.
  • Use absolute URLs (or set metadataBase).

Canonicals: stop duplicate URL problems

Canonicals tell search engines which URL is the “main” one when multiple URLs show the same content. Common duplicate sources: trailing slash vs no slash, query parameters, and http vs https.

Canonical best practices

  • Always use absolute canonical URLs (or ensure they resolve to absolute via metadataBase).
  • Canonical should match your preferred host/protocol and trailing slash rule.
  • Don’t canonical everything to the homepage.

Example canonical for a post

// app/posts/[slug]/page.tsx (inside metadata generator)
alternates: { canonical: `/posts/${slug}` }

Robots meta: index, noindex, and staging safety

Use robots meta to control indexing behavior. Production pages you want to rank should be indexable. Staging should be blocked and/or noindexed.

Practical rules

  • Production: index, follow (default).
  • Staging: noindex + block crawling via robots.txt (and ideally protect with auth).
  • Thin pages: consider noindex (e.g., internal utility pages).

Dynamic metadata for blog posts (App Router)

For blog posts, generate metadata per slug. This ensures each post has unique title, description, OG tags, and canonical.

Example generateMetadata

// app/posts/[slug]/page.tsx
import type { Metadata } from "next";

// Example: replace with your data source
async function getPost(slug: string) {
  return {
    title: "Next.js Metadata: Titles, Descriptions, OG, and Canonicals",
    description:
      "Learn Next.js metadata best practices: titles, descriptions, Open Graph, Twitter cards, and canonical URLs—plus per-route patterns.",
    ogImage: "/assets/og-cover.png"
  };
}

export async function generateMetadata(
  { params }: { params: { slug: string } }
): Promise<Metadata> {
  const post = await getPost(params.slug);

  return {
    title: post.title,
    description: post.description,
    alternates: {
      canonical: `/posts/${params.slug}`
    },
    openGraph: {
      type: "article",
      title: post.title,
      description: post.description,
      url: `https://blog.olamisan.com/posts/${params.slug}`,
      images: [{ url: post.ogImage, width: 1200, height: 630, alt: post.title }]
    },
    twitter: {
      card: "summary_large_image",
      title: post.title,
      description: post.description,
      images: [post.ogImage]
    }
  };
}

Tip: keep descriptions consistent and avoid auto-generating messy text from markdown.

Before-you-ship checklist

  • ✅ Unique title for each page
  • ✅ Helpful description that matches the page
  • ✅ Correct canonical (preferred host/protocol/slash rule)
  • ✅ Open Graph + Twitter preview looks correct
  • ✅ Staging has noindex + robots blocking + auth (recommended)
  • ✅ No accidental noindex shipped to production

Related: Technical SEO basicsRobots + sitemap setup

FAQ

How do I set a canonical URL in Next.js App Router?

Use the metadata API and set alternates.canonical. Keep it consistent with your preferred URL format.

Should every page have a unique title and description?

Yes. Use a consistent template, but customize the page-specific part so pages don’t look duplicated.

Do Open Graph tags matter for SEO?

Not directly for ranking, but they improve how your content appears when shared, increasing clicks.

How do I prevent staging sites from being indexed?

Add auth, use noindex on staging, and block crawling via robots.txt for the staging domain.

Related reading