Add metadata in a Next.js application built with the Pages and the App Router

Metadata helps search engines understand what a page is about and index it accordingly. For optimal SEO performance and for web pages to be ranked and found on search engines, it is crucial that the pages have proper metadata.

Now, some metadata are global and need to be on every page, while some are local or specific to a page. Let's see how we add both in a Next.js app built with the Pages and the App Router.

Add metadata in the Pages Router

Global metadata

In the Pages Router, we add global metadata in a special file called _document.tsx.

import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
  return (
    <Html lang='en'>
      <Head>
        <meta charSet='UTF-8' />
        <meta
          name='robots'
          content='index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1'
        />
        <meta property='og:locale' content='en_US' />
        <meta name='author' content='Alamin Shaikh' />
        <meta property='og:image:width' content='920' />
        <meta property='og:image:height' content='470' />
        <meta name='twitter:card' content='summary_large_image' />
        <meta
          property='og:site_name'
          content='Developing Superior Software for Leading Businesses'
        />
        <meta
          name='keywords'
          content='JavaScript developer, TypeScript developer, Web developer'
        />
      </Head>

      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

Copy the meta elements from the above Head component and paste them within the Head component in the _document.tsx file of your project. Update the author, og:site_name, and keywords to match your project's details.

Local metadata

In the Pages Router, we use a CustomHead component to add local metadata specific to a page.

import Head from 'next/head';

type Props = {
  title: string;
  content: string;
  pageSlug: string;
  pageType?: string;
  ogImage?: string;
};

export default function CustomHead({
  title,
  content,
  pageSlug,
  pageType = 'website',
  ogImage = `${process.env.NEXT_PUBLIC_BASE_URL}/layout/og-image.png`,
}: Props) {
  const ogTitle = title.replace(' - Alamin Shaikh', '');
  const pageURL = `${process.env.NEXT_PUBLIC_BASE_URL}${pageSlug}`;

  return (
    <Head>
      <title>{title}</title>
      <meta name='description' content={content} />
      <link rel='canonical' href={pageURL} />
      <meta property='og:type' content={pageType} />
      <meta property='og:title' content={ogTitle} />
      <meta property='og:description' content={content} />
      <meta property='og:url' content={pageURL} />
      <meta property='og:image' content={ogImage} />
    </Head>
  );
}

As you can see, the above CustomHead component receives five props. Three of the props: title, content, and pageSlug are required and are unique to each page. The rest of the props: pageType and ogImage are optional.

Notice that we have default values for the pageType and ogImage props, so if they are not provided, the default ones will be used. Within the component, we create two variables: ogTitle and pageURL from the title and pageSlug props respectively.

From the component, we return the Head component provided by Next.js with a title, link, and a few meta elements. Following is a brief description of the elements:

To use this component in your Next.js application, create an environment variable named NEXT_PUBLIC_BASE_URL and change ' - Alamin Shaikh' to match your site's branding.

Now, let's see an example of using the CustomHead component on a page.

import Hero from '@components/home/Hero';
import CustomHead from '@components/layout/CustomHead';

export default function HomePage() {
  return (
    <>
      <CustomHead
        pageSlug='/'
        title='Full Stack JavaScript Developer - Alamin Shaikh'
        content='I am a full stack JavaScript developer specializing in web application development. I write technical articles about JavaScript and freelancing.'
      />
      <Hero />
    </>
  );
}

In the above code, we've used the CustomHead component on the homepage to add metadata about the page.

Add metadata in the App Router

Global metadata

In the App Router, we add global metadata by exporting a metadata object from the root layout.tsx file.

export const metadata: Metadata = {
  robots: {
    index: true,
    follow: true,
    'max-snippet': -1,
    'max-video-preview': -1,
    'max-image-preview': 'large',
  },
  authors: [{ name: 'Alamin Shaikh' }],
  keywords:
    'JavaScript developer, TypeScript developer, Web application developer, React.js web developer, Next.js developer, Progressive web app developer, Node.js developer, Express.js backend developer, JavaScript backend developer, RESTful API developer, TypeScript backend implementation, Full stack JavaScript developer, Full stack TypeScript developer, MERN stack developer, React native developer, Mobile application developer, Native application developer, MongoDB database expert',
  twitter: {
    card: 'summary_large_image',
  },
  metadataBase: new URL('https://www.alaminshaikh.com'),
};

Copy the above metadata object and paste it into the root layout.tsx file of your project. Update the authors, keywords, and metadataBase to match your project's details.

Local metadata

In the App Router, we add local metadata by exporting a metadata object from the page.tsx file.

export const metadata: Metadata = {
  title: 'Full Stack JavaScript Developer | Alamin Shaikh',
  description:
    'I am a full stack JavaScript developer specializing in web application development. I write technical articles about JavaScript and freelancing.',
  openGraph: {
    url: '/',
    type: 'website',
    locale: 'en_US',
    images: '/layout/og-image.png',
    title: 'Full Stack JavaScript Developer',
    siteName: 'Developing Superior Software for Leading Businesses',
  },
  alternates: {
    canonical: '/',
  },
};

As you can see in the above code, we export a metadata object from the homepage with the necessary metadata specific to the page.

Once you've added the metadata, inspect the page elements, and you should find all the local and global metadata you've added to the page. If you find the elements, your setup is working as intended.

That's it! If you are interested in learning to add favicon in a Next.js application, I have an article on Add favicon in a Next.js application built with the Pages and the App Router that provides further insights. Happy learning!

Share this article with your friends

Copy URL

Elevate your JavaScript and freelance journey

Supercharge your JavaScript skills and freelance career. Subscribe now for expert tips and insights!