Gitvurl

Gitvurl AI Studio/Oct 5, 2026/5 min read

How Next.js Metadata Templates Change the Title a Crawler Sees

Discover how Next.js's App Router metadata templates allow dynamic title generation, influencing how search engines and social platforms interpret your page's title for link previews.

Next.js metadataApp Routercrawler titlelink previewsOpen GraphTwitter Cards

When you share a link on platforms like GitHub, Discord, or Slack, you expect a rich preview โ€“ a title, description, and an image. This preview is generated by bots that crawl your page, looking for specific metadata. In modern web development, especially with frameworks like Next.js, managing this metadata has become more sophisticated, particularly with the introduction of the App Router and its metadata object. Understanding how these templates affect the title a crawler sees is crucial for ensuring your link previews are accurate and appealing.

The Default Behavior: What Crawlers See Without Templates

Traditionally, crawlers primarily looked at the <title> tag within your HTML's <head> section. This was the most straightforward way to determine the title of a web page. For example, a simple index.html might look like this:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Awesome Blog Post</title>
  <meta name="description" content="A detailed look at why this post is awesome.">
  <meta property="og:title" content="My Awesome Blog Post">
  <meta property="og:description" content="A detailed look at why this post is awesome.">
  <meta property="og:image" content="https://example.com/image.jpg">
  <meta name="twitter:card" content="summary_large_image">
</head>
<body>
  <h1>The Content of My Awesome Blog Post</h1>
  <p>This is the main content of the post.</p>
</body>
</html>

In this scenario, any crawler, whether it's Googlebot or a social media bot, would likely pick up "My Awesome Blog Post" as the title. The Open Graph (og:title) and Twitter Card (twitter:title, though not explicitly used here but implied by twitter:card) tags are also important for rich previews, often taking precedence if available. However, the fundamental title source is still the <title> tag.

Introducing Next.js App Router Metadata

Next.js's App Router offers a powerful way to manage metadata, including titles, through a metadata object exported from layout.js or page.js files. This approach allows for dynamic generation of metadata based on the page's content or URL. The metadata object can be a static object or a function that returns a Promise, enabling asynchronous operations like fetching data.

When you define metadata this way, Next.js automatically generates the necessary <head> tags for you. The structure is intuitive:

// app/page.js or app/layout.js

export const metadata = {
  title: 'My Dynamic Page Title',
  description: 'A dynamic description for my page.',
  openGraph: {
    title: 'My Dynamic Page Title - Open Graph',
    description: 'A dynamic description for my page.',
    images: ['https://example.com/og-image.jpg'],
  },
  twitter: {
    card: 'summary_large_image',
    title: 'My Dynamic Page Title - Twitter',
    description: 'A dynamic description for my page.',
    image: 'https://example.com/twitter-image.jpg',
  },
};

export default function Page() {
  return <h1>Welcome to My Dynamic Page</h1>;
}

Static Metadata in Next.js

In the example above, title directly sets the content for the <title> tag. The openGraph.title and twitter.title properties are also crucial. When a crawler, like those used by GitHub for link previews or Discord for embeds, visits your page, it will prioritize the most specific metadata available. Generally, og:title will be used for Open Graph-compatible platforms, and twitter:title for Twitter Card-compatible platforms. If these aren't present, it falls back to the main <title> tag.

Dynamic Metadata with `generateMetadata`

The real power comes with the generateMetadata function. This allows you to fetch data or perform logic to create metadata on the fly. For instance, if you have a blog post page where the title is stored in a database:

// app/posts/[slug]/page.js

async function getPostData(slug) {
  // Imagine this fetches data from a CMS or database
  const res = await fetch(`https://api.example.com/posts/${slug}`);
  const post = await res.json();
  return post;
}

export async function generateMetadata({ params }) {
  const post = await getPostData(params.slug);

  if (!post) {
    return {
      title: 'Post Not Found',
    };
  }

  return {
    title: post.title, // This becomes the <title> tag
    description: post.excerpt,
    openGraph: {
      title: `${post.title} - My Blog`,
      description: post.excerpt,
      images: [post.featuredImage.url],
    },
    twitter: {
      card: 'summary_large_image',
      title: `${post.title} - My Blog`,
      description: post.excerpt,
      image: post.featuredImage.url,
    },
  };
}

export default async function PostPage({ params }) {
  const post = await getPostData(params.slug);

  if (!post) {
    return <div>Post not found</div>;
  }

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
}

In this dynamic example, the title property directly within generateMetadata dictates what the <title> tag will render. Crucially, when a crawler fetches this page, the server-side rendering (SSR) or static site generation (SSG) process will resolve generateMetadata. The crawler receives the fully rendered HTML, including the <title> tag populated with the fetched post.title.

Social media platforms and chat applications use bots (crawlers) to fetch and parse the HTML of a shared URL. These bots look for specific meta tags to construct link previews.

  1. Open Graph Protocol (`og:`): Widely used by Facebook, LinkedIn, Slack, Discord, and others. The og:title tag is the primary source for the preview's title. If og:title is absent, they might fall back to the <title> tag.
  2. Twitter Card tags (`twitter:`): Used by Twitter and sometimes other platforms that support Twitter Card markup. twitter:title is the preferred title here. If absent, it might fall back to og:title or the <title> tag.
  3. Standard HTML `<title>` tag: The fundamental HTML tag for a page's title. This is the ultimate fallback. If no Open Graph or Twitter Card titles are found, crawlers will use the content of this tag.

With Next.js's App Router metadata API, you are effectively telling the framework how to generate these tags. When generateMetadata is used, Next.js ensures that the dynamic title value (or og:title, twitter:title) is correctly placed within the <head> of the rendered HTML. A crawler fetching the page will parse this HTML and extract the title from the most relevant meta tag.

The Role of `gitvurl.com` in Preview Generation

Services like gitvurl.com are invaluable for testing and ensuring your link previews behave as expected. Before sharing a link widely, you can use a tool like Gitvurl to preview exactly what your link will look like when shared on various platforms. This helps catch issues where the wrong title might be displayed, perhaps due to incorrect metadata configuration or caching problems.

For example, you might input your Next.js page URL into Gitvurl and see the generated preview. If the title isn't what you intended, you can then revisit your metadata object or generateMetadata function. You might realize that while your <title> tag is correct, your og:title is missing or malformed. Gitvurl provides immediate feedback, allowing you to iterate quickly. You can check your GitHub link preview setup or Discord unfurl behavior with certainty.

Hashtags ยท 6

Next.js metadata App Router crawler title link previews Open Graph Twitter Cards

Create your first AI Ad on GitvurlStart