Documentation

App Router Metadata

Integrate SEO Manager with the Next.js App Router metadata system.

App Router Metadata

The nextjs-seo-manager/metadata module provides helpers for integrating SEO Manager with the Next.js App Router metadata system. It uses React cache() so that generateMetadata and your page component share a single API call per request.

If you are using the Pages Router, see SEOHelper instead.

Exports

ExportTypeDescription
createPageSEOfunctionFactory that creates cached SEO helpers for a page
AppSEOHelpercomponentClient component for ld+json and analytics pings
buildMetadataFromSEOfunctionMaps SEO data to a Next.js Metadata object (advanced)
mapFetchSEOToMetadatafunctionNormalizes raw fetchSEO data with defaults (advanced)

Quick Start

// app/dinner/page.tsx
import SEOInit from "nextjs-seo-manager/init";
import { createPageSEO, AppSEOHelper } from "nextjs-seo-manager/metadata";

SEOInit({
  projectId: process.env.SEO_MANAGER_PROJECT_ID,
  secretKey: process.env.SEO_MANAGER_SECRET_KEY,
  projectKey: process.env.NEXT_PUBLIC_SEO_MANAGER_PROJECT_KEY,
});

const DEFAULTS = {
  title: "Dinner Menu",
  description: "Browse our dinner menu",
};

const pageSEO = createPageSEO("/dinner", DEFAULTS);

export const generateMetadata = pageSEO.generateMetadata;

export default async function DinnerPage() {
  const seo = await pageSEO.getSEOData();
  return (
    <>
      <AppSEOHelper data={seo} />
      <h1>Dinner Menu</h1>
      {/* your page content */}
    </>
  );
}

createPageSEO

PropertyTypeRequiredDescription
pathstringYesThe page path to fetch SEO data for. Must begin with '/'.
defaultsSEODefaultsNoDefault SEO values used as fallbacks when the dashboard has no data.
optionsobjectNoAdditional metadata options. Shape: { metadataOptions: SEOMetadataOptions, meta: { request: object } }

createPageSEO(path, defaults?, options?) returns an object with two methods:

  • generateMetadata() — an async function that returns a Next.js Metadata object. Export it directly as generateMetadata from your page file. It populates title, description, keywords, openGraph, twitter, alternates.canonical, and robots.
  • getSEOData() — an async function that returns the full SEO data (including _ping config for analytics). Pass the result to AppSEOHelper.

Both methods use the same cached fetch, so the API is only called once per request even though both are invoked.

SEODefaults

PropertyTypeDescription
titlestringDefault page title used when no title is set in the dashboard.
descriptionstringDefault page description used when no description is set in the dashboard.
keywordsstringDefault keywords string.
imagestringDefault Open Graph image URL.
canonicalstringDefault canonical URL.
pathstringDefault page path. Used to construct the canonical URL if not explicitly set.

Fallback values used when the dashboard has no data for a field. For example, if no title is set for a page in the dashboard, defaults.title is used instead.

SEOMetadataOptions

PropertyTypeDescription
structuredDataobjectCustom JSON-LD structured data to include in the metadata. Overrides any structured data from the dashboard.
robotsOverrideobjectOverride the robots index/follow settings. Shape: { index: boolean, follow: boolean }

AppSEOHelper

PropertyTypeRequiredDescription
dataobjectYesThe SEO data object returned by createPageSEO().getSEOData(). Contains page data, global settings, and analytics ping configuration.

A client component ("use client") that renders what generateMetadata cannot:

  • ld+json structured data<script type="application/ld+json"> tags for the page's ldJson and events data.
  • Analytics ping — fires a request to the SEO Manager API on each navigation to track page views.

AppSEOHelper does not render meta tags — those are handled by generateMetadata.

buildMetadataFromSEO (Advanced)

For cases where you need more control over the metadata object, you can use buildMetadataFromSEO directly:

import { fetchSEO } from "nextjs-seo-manager";
import { buildMetadataFromSEO } from "nextjs-seo-manager/metadata";

export async function generateMetadata() {
  const seoData = await fetchSEO("/custom-page");
  return buildMetadataFromSEO(seoData, {
    title: "Fallback Title",
    description: "Fallback description",
  }, {
    robotsOverride: { index: true, follow: true },
  });
}

The returned metadata includes: title, description, keywords, openGraph (title, description, images, type, locale), twitter (card, title, description, images), alternates.canonical, and robots.

Full Example with Layout

// app/layout.tsx
import SEOInit from "nextjs-seo-manager/init";

SEOInit({
  projectId: process.env.SEO_MANAGER_PROJECT_ID,
  secretKey: process.env.SEO_MANAGER_SECRET_KEY,
  projectKey: process.env.NEXT_PUBLIC_SEO_MANAGER_PROJECT_KEY,
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}
// app/about/page.tsx
import { createPageSEO, AppSEOHelper } from "nextjs-seo-manager/metadata";

const pageSEO = createPageSEO("/about", {
  title: "About Us",
  description: "Learn about our company",
  canonical: "https://example.com/about",
});

export const generateMetadata = pageSEO.generateMetadata;

export default async function AboutPage() {
  const seo = await pageSEO.getSEOData();
  return (
    <>
      <AppSEOHelper data={seo} />
      <h1>About Us</h1>
      <p>Welcome to our company.</p>
    </>
  );
}

For App Router robots.txt and sitemaps, see Robots.txt and Sitemaps.

Explore

More documentation

Getting Started

Set up nextjs-seo-manager for your Next.js project.