Command Palette

Search for a command to run...

SEO & Metadata

Optimize your Next.js application for search engines with ready-to-use code snippets.

Next.js includes a Metadata API that allows you to define metadata to improve your application's SEO. This guide includes ready-to-copy examples for your Next.js project.

Below is a complete example of the metadata setup, so you can easily copy it into your app/layout.jsx

export const metadata = {  metadataBase: new URL("https://yourdomain.com"),  title: {    default: "My Application - Main Tagline",    template: "%s | My Application",  },  description: "The best web application for your needs. Detailed description of what you offer.",  keywords: ["nextjs", "react", "web app", "seo", "typescript"],  authors: [{ name: "Your Name", url: "https://yourdomain.com" }],  creator: "Your Name",  publisher: "Your Company",    // Open Graph  openGraph: {    title: "My Application",    description: "The best web application for your needs",    url: "https://yourdomain.com",    siteName: "My Application",    images: [      {        url: "/og-image.jpg",        width: 1200,        height: 630,        alt: "My Application Preview",      },    ],    locale: "en_US",    type: "website",  },    // Twitter  twitter: {    card: "summary_large_image",    title: "My Application",    description: "The best web application for your needs",    creator: "@yourusername",    images: ["/twitter-image.jpg"],  },    // Robots  robots: {    index: true,    follow: true,    googleBot: {      index: true,      follow: true,      "max-video-preview": -1,      "max-image-preview": "large",      "max-snippet": -1,    },  },    // Icons  icons: {    icon: "/icon.png",    shortcut: "/shortcut-icon.png",    apple: "/apple-icon.png",  },    // Verification  verification: {    google: "your-google-verification-code",  },    // Alternates  alternates: {    canonical: "https://yourdomain.com",  },};

For pages with dynamic content (blogs, products, etc.), use generateMetadata()

export async function generateMetadata({ params }) {  const { slug } = await params;    // Fetch data  const post = await fetch(`https://api.yourdomain.com/posts/${slug}`)    .then((res) => res.json());    return {    title: post.title,    description: post.excerpt,    openGraph: {      title: post.title,      description: post.excerpt,      images: [        {          url: post.image,          width: 1200,          height: 630,        },      ],      type: "article",      publishedTime: post.publishedAt,      authors: [post.author.name],    },    twitter: {      card: "summary_large_image",      title: post.title,      description: post.excerpt,      images: [post.image],    },  };}export default function BlogPost({ params }) {  // Your component...}

Automatically generate Open Graph images using Next.js. Create app/opengraph-image.tsx or app/[route]/opengraph-image.tsx for dynamic routes. Next.js will automatically generate the image and add the correct meta tags.

import { ImageResponse } from 'next/og';// Image metadataexport const alt = 'My Application';export const size = {  width: 1200,  height: 630,};export const contentType = 'image/png';// Image generationexport default async function Image() {  return new ImageResponse(    (      <div        style={{          fontSize: 128,          background: 'white',          width: '100%',          height: '100%',          display: 'flex',          alignItems: 'center',          justifyContent: 'center',        }}      >        My Application      </div>    ),    {      ...size,    }  );}

import { ImageResponse } from 'next/og';export const alt = 'Blog Post';export const size = {  width: 1200,  height: 630,};export const contentType = 'image/png';export default async function Image({ params }) {  const { slug } = await params;    // Fetch post data  const post = await fetch(`https://api.yourdomain.com/posts/${slug}`)    .then((res) => res.json());  return new ImageResponse(    (      <div        style={{          fontSize: 48,          background: 'white',          width: '100%',          height: '100%',          display: 'flex',          alignItems: 'center',          justifyContent: 'center',        }}      >        {post.title}      </div>    ),    {      ...size,    }  );}

Next.js automatically generates sitemap.xml and robots.txt files. Create app/sitemap.js and app/robots.js in your app directory. These files will be automatically served at /sitemap.xml and /robots.txt.

export default function sitemap() {  return [    {      url: "https://yourdomain.com",      lastModified: new Date(),      changeFrequency: "yearly",      priority: 1,    },    {      url: "https://yourdomain.com/about",      lastModified: new Date(),      changeFrequency: "monthly",      priority: 0.8,    },    {      url: "https://yourdomain.com/blog",      lastModified: new Date(),      changeFrequency: "weekly",      priority: 0.5,    },  ];}

export default function robots() {  return {    rules: {      userAgent: "*",      allow: "/",      disallow: ["/admin/", "/api/"],    },    sitemap: "https://yourdomain.com/sitemap.xml",  };}

Additional SEO Tips

  • OG Images: Use 1200x630px for Open Graph (Facebook, LinkedIn)
  • Twitter Images: 1200x600px works best for Twitter Cards
  • Description: Between 150-160 characters is ideal for Google
  • Title: Maximum 60 characters to avoid truncation in results
  • Keywords: 5-10 relevant keywords is sufficient