Fumadocs
Integrations

Open Graph

Open Graph with Next.js Metadata API

Introduction

Next.js provides an useful set of utilities, allowing a flexible experience with Fumadocs. Fumadocs uses the Next.js Metadata API for SEO.

Make sure to read their Metadata section for the fundamentals of Metadata API.

Open Graph Image

For docs pages, Fumadocs UI has a built-in dynamic image generator.

You will need a route handler to get started.

app/og/[...slug]/route.tsx
import { generateOGImage } from 'fumadocs-ui/og';
import { type NextRequest } from 'next/server';
import { notFound } from 'next/navigation';
import { source } from '@/app/source';
 
export function GET(
  _: NextRequest,
  { params }: { params: { slug: string[] } },
) {
  const page = source.getPage(params.slug.slice(0, -1));
  if (!page) notFound();
 
  return generateOGImage({
    title: page.data.title,
    description: page.data.description,
    site: 'My App',
  });
}
 
export function generateStaticParams() {
  return source.generateParams().map((params) => ({
    ...params,
    slug: [...params.slug, 'og.png'],
  }));
}

We need to append og.png to the end of slugs so that we can access it via /og/my-page/og.png.

In your docs page, add the image to metadata.

app/docs/[[...slug]]/page.tsx
import { source } from '@/app/source';
import type { Metadata } from 'next';
import {
  DocsPage,
  DocsBody,
  DocsTitle,
  DocsDescription,
} from 'fumadocs-ui/page';
import { notFound } from 'next/navigation';
import defaultMdxComponents from 'fumadocs-ui/mdx';
import { getImageMeta } from 'fumadocs-ui/og';
 
export default async function Page({
  params,
}: {
  params: { slug?: string[] };
}) {
  const page = source.getPage(params.slug);
  if (!page) notFound();
 
  const MDX = page.data.body;
 
  return (
    <DocsPage toc={page.data.toc} full={page.data.full}>
      <DocsTitle>{page.data.title}</DocsTitle>
      <DocsDescription>{page.data.description}</DocsDescription>
      <DocsBody>
        <MDX components={{ ...defaultMdxComponents }} />
      </DocsBody>
    </DocsPage>
  );
}
 
export async function generateStaticParams() {
  return source.generateParams();
}
 
export function generateMetadata({ params }: { params: { slug?: string[] } }) {
  const page = source.getPage(params.slug);
  if (!page) notFound();
 
  const image = getImageMeta('og', page.slugs);
 
  return {
    title: page.data.title,
    description: page.data.description,
    openGraph: {
      images: image,
    },
    twitter: {
      images: image,
      card: 'summary_large_image',
    },
  } satisfies Metadata;
}

You can also customise the font, options for Satori are also available on the built-in generator.

import { generateOGImage } from 'fumadocs-ui/og';
 
generateOGImage({
  fonts: [
    {
      name: 'Roboto',
      // Use `fs` (Node.js only) or `fetch` to read the font as Buffer/ArrayBuffer and provide `data` here.
      data: robotoArrayBuffer,
      weight: 400,
      style: 'normal',
    },
  ],
});

Last updated on

On this page

Edit on GitHub