Next.jsSEOMetadataTutorial

Next.js Metadata API: Improving SEO

Master the Next.js Metadata API to improve your site's SEO. Learn how to add metadata, Open Graph tags, Twitter cards, and structured data.

By Vibe Code Basics11 min read
Next.js Metadata API: Improving SEO

Next.js Metadata API: Improving SEO

SEO (Search Engine Optimization) is crucial for making your website discoverable. Next.js provides a powerful Metadata API that makes it easy to add SEO-friendly metadata to your pages. Let's explore how to use it effectively.

If you're new to Next.js, start with our Getting Started with Next.js guide.

Why Metadata Matters

Proper metadata helps:

  • Search engines understand your content
  • Social media display rich previews
  • Users see relevant information in search results
  • Improve click-through rates with better descriptions

Basic Metadata

In the App Router, export a metadata object from your page:

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

export default function About() {
  return <div>About page</div>;
}

Metadata in Layouts

You can define metadata in layouts, which will be inherited by child pages:

// app/layout.js
export const metadata = {
  title: {
    default: 'My Website',
    template: '%s | My Website',
  },
  description: 'Welcome to my website',
};

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

The template allows child pages to set their title, which will be formatted as "Page Title | My Website".

Open Graph Metadata

Open Graph tags control how your content appears when shared on social media:

export const metadata = {
  title: 'My Blog Post',
  description: 'An amazing blog post',
  openGraph: {
    title: 'My Blog Post',
    description: 'An amazing blog post',
    url: 'https://example.com/blog/my-post',
    siteName: 'My Website',
    images: [
      {
        url: 'https://example.com/og-image.jpg',
        width: 1200,
        height: 630,
        alt: 'Blog post image',
      },
    ],
    locale: 'en_US',
    type: 'article',
  },
};

Twitter Card Metadata

Add Twitter-specific metadata:

export const metadata = {
  title: 'My Blog Post',
  description: 'An amazing blog post',
  twitter: {
    card: 'summary_large_image',
    title: 'My Blog Post',
    description: 'An amazing blog post',
    images: ['https://example.com/twitter-image.jpg'],
  },
};

Dynamic Metadata

For dynamic metadata, use the generateMetadata function:

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

export default async function BlogPost({ params }) {
  const { slug } = await params;
  const post = await getPost(slug);
  
  return <article>{/* Post content */}</article>;
}

Structured Data (JSON-LD)

For advanced SEO, add structured data using JSON-LD:

export default function BlogPost({ post }) {
  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'BlogPosting',
    headline: post.title,
    description: post.description,
    image: post.image,
    datePublished: post.publishedAt,
    author: {
      '@type': 'Person',
      name: post.author,
    },
  };

  return (
    <>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
      />
      <article>{/* Post content */}</article>
    </>
  );
}

Complete Example: Blog Post

Here's a complete example for a blog post:

// app/blog/[slug]/page.js
export async function generateMetadata({ params }) {
  const { slug } = await params;
  const post = await getPost(slug);
  
  const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://example.com';
  const url = `${siteUrl}/blog/${slug}`;
  
  return {
    title: post.title,
    description: post.description,
    keywords: post.tags.join(', '),
    authors: [{ name: post.author }],
    openGraph: {
      title: post.title,
      description: post.description,
      url,
      siteName: 'My Blog',
      images: [
        {
          url: post.image,
          width: 1200,
          height: 630,
          alt: post.title,
        },
      ],
      locale: 'en_US',
      type: 'article',
      publishedTime: post.publishedAt,
      tags: post.tags,
    },
    twitter: {
      card: 'summary_large_image',
      title: post.title,
      description: post.description,
      images: [post.image],
    },
  };
}

Metadata Best Practices

  1. Unique titles: Each page should have a unique title
  2. Descriptive descriptions: Write compelling, accurate descriptions
  3. Relevant images: Use high-quality, relevant images for social sharing
  4. Proper URLs: Always use absolute URLs for Open Graph
  5. Structured data: Add JSON-LD for rich search results
  6. Mobile-friendly: Ensure your site works well on mobile devices

Testing Metadata

View Page Source

Check the <head> section to see your metadata.

Use Tools

  • Google Rich Results Test: Test structured data
  • Facebook Sharing Debugger: Test Open Graph tags
  • Twitter Card Validator: Test Twitter cards
  • Lighthouse: Check SEO score

Common Metadata Fields

export const metadata = {
  // Basic
  title: 'Page Title',
  description: 'Page description',
  
  // SEO
  keywords: ['keyword1', 'keyword2'],
  authors: [{ name: 'Author Name' }],
  creator: 'Creator Name',
  publisher: 'Publisher Name',
  
  // Open Graph
  openGraph: {
    title: 'OG Title',
    description: 'OG Description',
    url: 'https://example.com',
    siteName: 'Site Name',
    images: [],
    locale: 'en_US',
    type: 'website',
  },
  
  // Twitter
  twitter: {
    card: 'summary',
    title: 'Twitter Title',
    description: 'Twitter Description',
    images: [],
  },
  
  // Robots
  robots: {
    index: true,
    follow: true,
    googleBot: {
      index: true,
      follow: true,
    },
  },
};

Conclusion

The Next.js Metadata API makes it easy to add comprehensive SEO metadata to your pages. By properly implementing metadata, you can significantly improve your site's discoverability and social sharing appearance.

Next Steps:

Happy optimizing! 🚀

Related Articles