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 has a built-in metadata image generator.

Auto Setup

pnpm fumadocs init og-image

Manual Setup

lib/metadata.ts
import { createMetadataImage } from 'fumadocs-core/server';
import { source } from '@/lib/source';
 
export const metadataImage = createMetadataImage({
  imageRoute: '/docs-og',
  source,
});

You will need a route handler to get started.

app/docs-og/[...slug]/route.tsx
import { generateOGImage } from 'fumadocs-ui/og';
import { metadataImage } from '@/lib/metadata';
 
export const GET = metadataImage.createAPI((page) => {
  return generateOGImage({
    title: page.data.title,
    description: page.data.description,
    site: 'My App',
  });
});
 
export function generateStaticParams() {
  return metadataImage.generateParams();
}

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

In your docs page, add the image to metadata.

app/docs/[[...slug]]/page.tsx
import { source } from '@/lib/source';
import {
  DocsPage,
  DocsBody,
  DocsTitle,
  DocsDescription,
} from 'fumadocs-ui/page';
import { notFound } from 'next/navigation';
import defaultMdxComponents from 'fumadocs-ui/mdx';
import { metadataImage } from '@/lib/metadata';
 
export default async function Page(props: {
  params: Promise<{ slug?: string[] }>;
}) {
  const params = await props.params;
  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 async function generateMetadata(props: {
  params: Promise<{ slug?: string[] }>;
}) {
  const params = await props.params;
  const page = source.getPage(params.slug);
  if (!page) notFound();
 
  return metadataImage.withImage(page.slugs, {
    title: page.data.title,
    description: page.data.description,
  });
}

Font

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',
    },
  ],
});
Edit on GitHub

Last updated on

On this page