# Fumadocs (Framework Mode, Next.js): Takumi
URL: /ja/docs/next/integrations/og/takumi
Source: https://raw.githubusercontent.com/fuma-nama/fumadocs/refs/heads/main/apps/docs/content/docs/(framework)/[framework]/integrations/og/takumi.ja.mdx

Takumi を統合して、フレームワークに依存しない高速なメタデータ画像生成を実現します。

## インストール [#installation]

```npm
npm install takumi-js
```

`takumi-js` は Node.js 上でネイティブバインディング (`@takumi-rs/core`) を読み込みます。サーバーバンドルに含まれないように、外部パッケージとして指定してください。

```ts title="next.config.ts"
import type { NextConfig } from 'next';

const config: NextConfig = {
  // [!code ++]
  serverExternalPackages: ['@takumi-rs/core'],
};
```

## メタデータ画像 [#metadata-image]

ページの画像 URL を返す関数を追加し、ドキュメントページのメタデータからその画像を参照します。

```ts tab="lib/source.ts"
// [!code ++:8]
export function getPageImageUrl(page: (typeof source)['$inferPage']) {
  const segments = [...page.slugs, 'image.webp'];

  return {
    segments,
    url: '/' + [page.locale, 'og', 'docs', ...segments].filter(Boolean).join('/'),
  };
}
```

```tsx tab="app/docs/[[...slug]]/page.tsx"
import { notFound } from 'next/navigation';
import { source, getPageImageUrl } 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: {
      // [!code ++]
      images: getPageImageUrl(page).url,
    },
  };
}
```

> `/docs/my-page` の画像は `/og/docs/my-page/image.webp` に配置されます。WebP 画像は PNG 画像よりもファイルサイズが小さいためです。PNG を生成したい場合は、代わりに `image.png` と `format: 'png'` を使用してください。

次に、画像を生成するルートを作成します。

```tsx title="app/og/docs/[...slug]/route.tsx"
import { getPageImageUrl, source } from '@/lib/source';
import { notFound } from 'next/navigation';
import { generateOGImage } from 'fumadocs-ui/og/takumi';

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 generateOGImage({
    title: page.data.title,
    description: page.data.description,
    site: 'My App',
    format: 'webp',
  });
}

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

> Takumi には全ウェイト (100-900) に対応した [`Geist`](https://vercel.com/font) フォントと `Geist Mono` フォントが同梱されているため、フォントの設定は不要です。

高度な使い方については、[Takumi のドキュメント](https://takumi.kane.tw/docs)を参照してください。

### その他のテンプレート [#other-templates]

利用できるテンプレートについては、[Takumi Templates](https://takumi.kane.tw/docs/templates) を参照してください。