How to Add Open Graph to Your Next.js App

The Open Graph protocol is used by many social media platforms. It provides information on how to display your webpage when shared on platforms like Facebook, Twitter, LinkedIn, and others. To be more discoverable you want to share your content on many social media platforms. In this blog we will learn how to add Open Graph to your Next.js App Router app.

Jordan Wu profile picture

Jordan Wu

5 min·Posted 

Sunrise Above a Sandy Beach Image.
Sunrise Above a Sandy Beach Image.
Table of Contents

What is Open Graph?

Open Graph is a protocol created by Facebook that defines how to add Open Graph tags to your web page to become a rich object in a social graph. A rich object refer to a web page or piece of content that has been optimized using Open Graph protocol tags to provide rich and detailed information when shared on social media platforms. These tags provide information about the title, description, image, and other attributes of your web page content. By defining Open Graph tags, you can control how your content is displayed, making it more attractive and engaging for users who come across it on social media. It's an important tool to ensure that your content looks its best when shared on social media platforms. This can help increase click-through rates and improve the overall visibility of the content across all social media platforms.

How to Add Open Graph

The Open Graph tags are <meta> HTML elements that are added inside your <head> HTML element on your web page. There are four required properties for every page:

  • og:title - The title of your web page.
  • og:type - The type of content on your web page.
  • og:image - An image URL that represents your content on your web page.
  • og:url - The canonical URL of your web page.

Optional Metadata:

  • og:audio - A URL to an audio file that goes with your content on your web page.
  • og:description - A one to two sentence description of your content on your web page.
  • og:determiner - The word that appears before title in a sentence. Can have the following value of a, an, the, "" or auto. Default to "".
  • og:locale - The locale in the format of language_TERRITORY. Default is en_US.
  • og:locale:alternate - An array of other locales this page is available in.
  • og:site_name - Your website name.
  • og:video - A URL to a video file that complements this object.

When adding media metadata like og:image, og:audio, or og:video they have optional properties, using og:image as an example:

  • og:image:url - Identical to og:image.
  • og:image:secure_url - An alternate url to use if the webpage requires HTTPS.
  • og:image:type - A MIME type for this image.
  • og:image:width - The number of pixels wide.
  • og:image:height - The number of pixels high.
  • og:image:alt - A description of what is in the image. If the page specifies an og:image it should specify og:image:alt.

The required Open Graph tag og:type Object Types may have the following values:

  • music.song - If your content is a song.
  • music.album - If your content is an album.
  • music.playlist - If your content is a playlist.
  • music.radio_station - If your content is a radio_station
  • video.movie - If your content is a movie.
  • video.episode - If your content is an episode.
  • video.tv_show - If your content is a tv show.
  • video.other - Same as video.movie.
  • article - If your content is an article.
  • book - If your content is a book.
  • profile - If your content is a profile.
  • website - Default.

How to Add Open Graph to Your Next.js App Router

To add Open Graph tags to your web page you will be using the following approaches generateMetadata and the static metadata object. The known limitations for these approaches is only Server components specifically page and layout can use either one of them but not both.

The static metadata object approach is great if you have a static web page and its best to add it on the page component file in your App Router.

File Imagepage.tsx
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Next.js',
  description: 'Next.js by Vercel is the full-stack React framework for the web.',
  openGraph: {
    title: 'Next.js',
    description: 'The React Framework for the Web',
    url: 'https://nextjs.org',
    siteName: 'Next.js',
    images: [
      {
        url: 'https://nextjs.org/og.png',
        width: 1200,
        height: 630,
      },
    ],
    locale: 'en_US',
    type: 'website',
  },
}

export default function Page() {}

Which will auto generate the following Open Graph tags:

<meta property="og:title" content="Next.js" />
<meta property="og:description" content="The React Framework for the Web" />
<meta property="og:url" content="https://nextjs.org/" />
<meta property="og:site_name" content="Next.js" />
<meta property="og:locale" content="en_US" />
<meta property="og:image:url" content="https://nextjs.org/og.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:type" content="website" />

The generateMetadata approach is used when you need to dynamically generate your metadata, for example your blog posts.

File Imagesrc/app/blog/[...slug]/page.tsx
import { allPosts } from 'contentlayer/generated'
import siteMetadata from '@/content/siteMetadata'
import { pathTo } from '@/utils/routes'

import type { Metadata } from 'next'

type Props = {
  params: { slug: string[] }
}

const postBySlug = allPosts.reduce((acc, post) => {
  acc[post.slug.toString()] = post
  return acc
}, {})

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const post = postBySlug[params.slug.toString()]
  const {
    description,
    imageDescription,
    imageUrl,
    lastModifiedDate,
    publishedDate,
    tags,
    title
  } = post

  return {
    title,
    description,
    openGraph: {
      title,
      description,
      url: siteMetadata.siteUrl + pathTo.blogPost(post.slug),
      siteName: siteMetadata.siteName,
      images: [
        {
          url: imageUrl,
          width: 1200,
          height: 630,
          alt: imageDescription,
        },
      ],
      locale: siteMetadata.locale,
      type: 'article',
      publishedTime: new Date(publishedDate).toString(),
      modifiedTime: new Date(lastModifiedDate).toString(),
      authors: [siteMetadata.siteUrl + pathTo.about],
      tags: tags,
    },
}

export default function Page() {}

Facebook recommends using images that are 1200 x 630 pixels and must not exceed 8 MB for og:image to get the best results.

If you don't pre-cache your web page. The first person who shares your content on your webpage will not see the rendered image. You can use the Sharing Debugger tool to pre-fetch Open Graph tags for your web page. It can be used to update the cache with new Open Graph tags if you made changes.

Sharing Debugger Example
Sharing Debugger Example
Missing properties warning for fb:app_id
Missing properties warning for fb:app_id

Note: If you’re seeing this warning, then don’t worry. Your code is correct, and your shared content will display properly. The fb:app_id meta tag is not required and can be ignored.

About the Author

Jordan Wu profile picture
Jordan is a full stack engineer with years of experience working at startups. He enjoys learning about software development and building something people want. What makes him happy is music. He is passionate about finding music and is an aspiring DJ. He wants to create his own music and in the process of finding is own sound.
Email icon image
Stay up to date

Get notified when I publish something new, and unsubscribe at any time.