---
title: "Generate page metadata and Open Graph tags"
slug: "generate-page-metadata-and-open-graph-tags"
abstract: "Learn how to generate <title>, metadata, and Open Graph tags for a page from Sitecore route fields, in both App Router and Pages Router Content SDK Next.js apps."
---
# Generate page metadata and Open Graph tags

Content SDK can generate a page's `<title>`, standard metadata tags, and Open Graph tags from fields returned as siblings of `Title` on a Sitecore route. This removes the need to hand-write `generateMetadata` logic, or `<head>` markup, for these fields in every page.

The following fields are supported when present on the route:

| Field                     | Output                                                                           |
| ------------------------- | -------------------------------------------------------------------------------- |
| `Title`                   | `<title>` (always the source for `<title>`; falls back to a default when absent) |
| `baseMetadataTitle`       | `<meta name="title">` (doesn't affect `<title>`)                                 |
| `baseMetadataDescription` | `<meta name="description">`                                                      |
| `baseMetadataKeywords`    | `<meta name="keywords">`                                                         |
| `baseMetadataAuthor`      | `<meta name="author">`                                                           |
| `baseOgTitle`             | `og:title`                                                                       |
| `baseOgDescription`       | `og:description`                                                                 |
| `baseOgImage`             | `og:image`, `og:image:width`, `og:image:height`, `og:image:alt`                  |
| `baseOgType`              | `og:type`                                                                        |

Every field maps to exactly one tag independently; there is no cross-field fallback. A field with no value simply omits its tag.

## Open Graph time tags

When `baseOgType` is set to a type that the Open Graph protocol defines a time tag for, the route's `published` and `updated` values (if present) are mapped to the matching tag:

| `baseOgType` value | Creation time tag        | Update time tag         |
| ------------------ | ------------------------ | ----------------------- |
| `article`          | `article:published_time` | `article:modified_time` |
| `book`             | `book:release_date`      | —                       |
| `music.album`      | `music:release_date`     | —                       |
| `video.movie`      | `video:release_date`     | —                       |
| `video.episode`    | `video:release_date`     | —                       |

> [!note]
> `published` and `updated` are populated on the route from the item's publish and modification timestamps, when available from the layout response.

## For App Router apps - `getPageMetadata`

Use `getPageMetadata` from `@sitecore-content-sdk/nextjs` as the return value of a page's `generateMetadata`:

```ts
import { Metadata } from 'next';
import { getPageMetadata } from '@sitecore-content-sdk/nextjs';

export const generateMetadata = async ({ params }: PageProps): Promise<Metadata> => {
  const { path, site, locale } = await params;
  const page = await client.getPage(path ?? [], { site, locale });

  return getPageMetadata(page?.layout.sitecore.route);
};
```

`getPageMetadata` returns a Next.js [`Metadata`](https://nextjs.org/docs/app/api-reference/functions/generate-metadata) object built from the route fields described in the preceding table.

## For Pages Router apps - `PageMetaTags`

Use the `PageMetaTags` component from `@sitecore-content-sdk/nextjs` in your layout to render the same tags via `next/head`:

```tsx
import { PageMetaTags } from '@sitecore-content-sdk/nextjs';

const Layout = ({ page }: LayoutProps): JSX.Element => {
  const { layout } = page;
  const { route } = layout.sitecore;

  return (
    <>
      <PageMetaTags route={route} />
      {/* ...rest of layout... */}
    </>
  );
};
```

`PageMetaTags` accepts the following props:

| Prop           | Type                                         | Description                                                                           |
| -------------- | -------------------------------------------- | ------------------------------------------------------------------------------------- |
| `route`        | `RouteData<PageMetadataRouteFields> \| null` | Route node from a Sitecore layout response, for example `page.layout.sitecore.route`. |
| `defaultTitle` | `string`                                     | Fallback for `<title>` when the route has no `Title` field. Defaults to `'Page'`.     |

`PageMetaTags` and `getPageMetadata` apply the same field-mapping rules, so both routers produce equivalent output.

## Extending your route fields type

If you declare a custom type for your route's `fields`, extend `PageMetadataFields` so the metadata fields are included:

```ts
import { PageMetadataFields, Field } from '@sitecore-content-sdk/nextjs';

export interface RouteFields extends PageMetadataFields {
  [key: string]: unknown;
  Title?: Field;
}
```
