Fumadocs

Takumi

集成 Takumi 以实现与框架无关且快速的元数据图片生成。

安装

🌐 Installation

npm install @takumi-rs/image-response

请确保将 @takumi-rs/image-response 添加到 serverExternalPackages(Next.js)或 external,具体取决于你使用的打包工具。

🌐 Make sure to add @takumi-rs/image-response to serverExternalPackages (Next.js) or external depends on what bundler you are using.

next.config.ts
import type { NextConfig } from 'next';

const config: NextConfig = {
  serverExternalPackages: ['@takumi-rs/image-response'],
};

元数据图片

🌐 Metadata Image

你可以使用 @takumi-rs/image-response 动态生成元数据图片。

🌐 You can generate metadata images dynamically using @takumi-rs/image-response.

在你的加载器下添加以下内容,并为页面定义图片元数据:

🌐 Add the following under your loader, and define image metadata for pages:

lib/source.ts
import { type InferPageType } from 'fumadocs-core/source';

export function getPageImage(page: InferPageType<typeof source>) {
  const segments = [...page.slugs, 'image.webp'];

  return {
    segments,
    url: `/og/docs/${segments.join('/')}`,
  };
}
app/docs/[[...slug]]/page.tsx
import { notFound } from 'next/navigation';
import { source, getPageImage } from '@/lib/source';
import type { Metadata } from 'next';

export async function generateMetadata(props: PageProps<'/docs/[[...slug]]'>): Promise<Metadata> {
  const params = await props.params;
  const page = source.getPage(params.slug);
  if (!page) notFound();

  return {
    title: page.data.title,
    description: page.data.description,
    openGraph: {
      images: getPageImage(page).url,
    },
  };
}

我们在 slugs 的末尾添加 image.webp,这样我们就可以通过 /og/docs/my-page/image.webp 访问它,从而获得更小的图片尺寸。如果你愿意,也可以使用 image.png

最后,创建一个路由处理程序以在构建时生成图片:

🌐 Finally, create a route handler to generate images at build time:

app/og/docs/[...slug]/route.tsx
import { getPageImage, source } from '@/lib/source';
import { notFound } from 'next/navigation';
import { ImageResponse } from '@takumi-rs/image-response';
import { generate as DefaultImage } from 'fumadocs-ui/og';

export const revalidate = false;

export async function GET(_req: Request, { params }: RouteContext<'/og/docs/[...slug]'>) {
  const { slug } = await params;
  const page = source.getPage(slug.slice(0, -1));
  if (!page) notFound();

  return new ImageResponse(
    <DefaultImage title={page.data.title} description={page.data.description} site="My App" />,
    {
      width: 1200,
      height: 630,
      format: 'webp',
    },
  );
}

export function generateStaticParams() {
  return source.getPages().map((page) => ({
    lang: page.locale,
    slug: getPageImage(page).segments,
  }));
}

Takumi 自带完整轴向(100-900)GeistGeist Mono 字体,因此你无需担心这个问题。

有关更多详细信息或高级用法,请参阅 Takumi 的文档

🌐 See Takumi's Documentation for more details or advanced usage.

其他模板

🌐 Other Templates

还有其他可用的模板,请参阅 Takumi 模板 获取完整列表。

🌐 There's other available templates, see Takumi Templates for a full list.

Last updated on

On this page