Next.js Dynamic Metadata with TypeScript

A type-safe approach to handling dynamic metadata in Next.js 14+ using the new metadata API


Next.js 14 introduced a new metadata API that makes it easier to handle dynamic metadata. Here's a type-safe implementation for handling dynamic metadata in your pages.

page.tsx
import type { Metadata } from "next";
import { reader } from "@/reader";
 
type Props = {
  params: { slug: string };
};
 
export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const post = await reader.collections.posts.read(params.slug);
 
  if (!post) {
    return {
      title: "Not Found",
      description: "The page you are looking for does not exist.",
    };
  }
 
  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: post.featuredImage ? [
        {
          url: `/images/posts/${post.featuredImage}`,
          width: 1200,
          height: 630,
          alt: post.title,
        },
      ] : undefined,
    },
    twitter: {
      card: "summary_large_image",
      title: post.title,
      description: post.excerpt,
      images: post.featuredImage ? [`/images/posts/${post.featuredImage}`] : undefined,
    },
  };
}

This implementation:

  • Uses TypeScript for type safety
  • Handles dynamic metadata based on content from your CMS
  • Includes OpenGraph and Twitter card metadata
  • Gracefully handles missing content
  • Supports both local and external images