Next.js - Metadata



Metadata of a webpage stores important information like webpage title, description, title card images, etc. Proper metadata is essential for better search engine results. In this chapter, we will explain metadata object in Next.js, how to define static and dynamic metadata, generate metadata image using CSS.

Metadata Object in Next.js

In Next.js, the metadata object is part of the App Router used to define metadata for each route. With metadata object, we can define title, description and other SEO components even for dynamically generated routes. Here is syntax of metadata object.

export const metadata = {
    title: "Title of Webpage",
    description: "Description of Webpage"
}

Title Attribute

The title attribute is used to set the title of the document. It can be defined as a simple string or an optional template object.

import type { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: {
    default: '...', 
    template: '...', 
    absolute: '...', 
  },
}
  • default : This default title value, that define fallback title to child routes
  • template : Used to add a prefix or a suffix to titles defined in child routes
  • absolute : Used to provide a title that ignores title.template set in parent route.

Declare a Static Metadata

Static metadata means the metadata that does not depend on data from external sources. This static meta data remains same for all users and it is defined while coding application.

In App router, you can define a static metadata by exporting a Metadata object from a 'layout.tsx' or static 'page.tsx' file. The metadata defined in layout.tsx will be accessible to all components in layout. A metadata defined in page.tsx will particular to that component and it can override metadata of layout page.

Example of Metadata of Layout Component

In the code below, we defined metadata for a layout component using Metadata object. The title we defined will be visible at top of browser tab.

// app/layout.tsx file

import { ReactNode } from 'react';
import type { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: 'Next JS Tutorial',
  description: 'We provide simple and easy to learn tutorial on Next JS',
}

interface RootLayoutProps {
  children: ReactNode;
}

export default function RootLayout({ children }: RootLayoutProps) {
  return (
    <html lang="en">
      <body>
        <header>
            <h1>Header Element</h1>
        </header>
        <main>{children}</main>
      </body>
    </html>
  );
}

Output

Here is the output of above code. The title metadata is highlighted in red rectangle.

next.js-static-metadata-layout

Example of Metadata for any Component

As mentioned above, we can override the metadata of layout page inside any component. In the example below we defined a new title and description for About page.

// app/about/page.tsx file

import type { Metadata } from 'next';
 
export const metadata: Metadata = {
  title: 'Next JS About Page',
  description: 'We provide simple and easy to learn tutorial on Next JS',
}

export default function About() {
    return (
        <div>
            <h1>About Us</h1>
            <h2>Welcome to the Next JS About page!</h2>
            <h4>This page is same for all users</h4>
        </div>
    );
}    

Output

This is the combined output of above two codes. You can see that the metadata defined in layout page is default metadata and it is overridden by metadata of About page when we open About page.

Static Meta data example

Declare a Dynamic Metadata

Dynamic metadata depends on dynamic information, such as the current route parameters, external data, or metadata in parent segments. It can be set by exporting a 'generateMetadata()' function that returns a Metadata object. Learn how dynamic routes works before going through the example.

Example of Dynamic Title Based on Route

In the example below, we will generate a dynamic title for component based on page selected by user.

// app/products/[id]/page.tsx

import { Metadata } from "next";

type Props ={
    params: {
        id: string;
    };
}
// Dynamic Metadata function
export const generateMetadata = ({ params }: Props): Metadata => {
    return {
        title: `Product ${params.id} - My Store`,
    };
}

export default function ProductPage({params }: Props) {

    return (
        <div>
            <h1>Product {params.id}</h1>
            <p>This is the product page for item {params.id}</p>
        </div>
    );
}

Output

In the output you can see that the page is changing based on route we choose.

Dynamic Meta Data

Metadata Image Generation

Metadata images are used for creating social media images such as Open Graph images, Twitter cards, and more. This image will be displayed when our link of our webpage is shared in Whatsapp, Twitter etc.

Example of Simple Hello World Image

The below example uses ImageResponse constructor to generate dynamic images using JSX and CSS. We will display the generated image in same webpage itself, so that you can see it in output.

// app/api/og/route.js

import { ImageResponse } from 'next/og';

export async function GET() {
  return new ImageResponse(
    (
      <div
        style={{
          fontSize: 50,
          background: 'grey',
          color: '#f0f0f0',
          width: '100%',
          height: '100%',
          display: 'flex',
          textAlign: 'center',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        Hello world!
      </div>
    ),
    {
      width: 300,
      height: 100,
    }
  );
}

// app/contacts/page.js

export default function Page() {
    return (
      <div>
        <h1>Contacts Page</h1>
        <img src="/api/og" alt="Generated Image" />
      </div>
    );
  }

Output

In the output below you can see generated image with 'Hello World' message.

Meta data image
Advertisements