Metadata & Head

Managing page titles, descriptions, and SEO in Next.js

🏷️ What is Metadata?

Metadata defines information about your web pages like titles, descriptions, and social media previews. Next.js provides a simple metadata API to manage SEO and improve how your pages appear in search results and social shares.


// app/page.js
export const metadata = {
  title: 'Home Page',
  description: 'Welcome to my website'
}
                                    

Metadata Types

Next.js supports various metadata types for SEO optimization. You can define static metadata using exports or generate dynamic metadata based on page parameters. This helps search engines understand your content and improves social media sharing.

📝

Static Metadata

Fixed metadata for pages

export const metadata = {
  title: 'About'
}
🔄

Dynamic Metadata

Generate metadata from data

export async function generateMetadata({ params }) {
  // Dynamic metadata generation logic here
}
🌐

Open Graph

Social media previews

export const metadata = {
  openGraph: {
    title: 'My Page'
  }
}
🐦

Twitter Cards

Twitter-specific metadata

export const metadata = {
  twitter: {
    card: 'summary'
  }
}

🔹 Basic Static Metadata

Add metadata to any page or layout using the metadata export:

// app/about/page.js
export const metadata = {
  title: 'About Us',
  description: 'Learn more about our company and mission',
  keywords: ['about', 'company', 'team'],
}

export default function AboutPage() {
  return <h1>About Us</h1>
}

Generates in HTML head:

<head>
  <title>About Us</title>
  <meta name="description" content="Learn more about our company and mission">
  <meta name="keywords" content="about, company, team">
</head>

🔹 Dynamic Metadata

Generate metadata based on route parameters or fetched data:

🔸 Blog Post Example

// app/blog/[slug]/page.js
export async function generateMetadata({ params }) {
  const post = await getPost(params.slug)
  
  return {
    title: post.title,
    description: post.excerpt,
  }
}

export default function BlogPost({ params }) {
  return <article>...</article>
}

For URL: /blog/nextjs-guide

<title>Next.js Complete Guide</title>
<meta name="description" content="Learn Next.js from scratch...">

🔹 Open Graph Metadata

Optimize how your pages appear when shared on social media:

// app/page.js
export const metadata = {
  title: 'My Website',
  description: 'Welcome to my amazing website',
  openGraph: {
    title: 'My Website',
    description: 'Welcome to my amazing website',
    url: 'https://mywebsite.com',
    siteName: 'My Website',
    images: [
      {
        url: 'https://mywebsite.com/og-image.jpg',
        width: 1200,
        height: 630,
      },
    ],
    type: 'website',
  },
}

Open Graph Benefits:

  • Rich previews on Facebook, LinkedIn
  • Custom images and descriptions
  • Better click-through rates
  • Professional appearance

🔹 Twitter Card Metadata

Customize how your pages look on Twitter/X:

// app/page.js
export const metadata = {
  twitter: {
    card: 'summary_large_image',
    title: 'My Website',
    description: 'Welcome to my amazing website',
    creator: '@myhandle',
    images: ['https://mywebsite.com/twitter-image.jpg'],
  },
}

Twitter Card Types:

  • summary: Small image card
  • summary_large_image: Large image card
  • app: Mobile app card
  • player: Video/audio player card

🔹 Metadata Template

Create consistent titles across your site with templates:

// app/layout.js
export const metadata = {
  title: {
    template: '%s | My Website',
    default: 'My Website',
  },
}

// app/about/page.js
export const metadata = {
  title: 'About',
}

// Renders as: "About | My Website"

🔹 Additional Metadata Options

More metadata fields for comprehensive SEO:

export const metadata = {
  title: 'My Page',
  description: 'Page description',
  
  // Robots
  robots: {
    index: true,
    follow: true,
  },
  
  // Icons
  icons: {
    icon: '/favicon.ico',
    apple: '/apple-icon.png',
  },
  
  // Verification
  verification: {
    google: 'google-site-verification-code',
  },
  
  // Alternate languages
  alternates: {
    canonical: 'https://mywebsite.com',
    languages: {
      'es-ES': 'https://mywebsite.com/es',
    },
  },
}

🧠 Test Your Knowledge

How do you add metadata to a Next.js page?