# Fumadocs (Framework Mode, React Router): Takumi
URL: /ja/docs/react-router/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
```

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

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

```tsx tab="app/lib/shared.ts"
export const docsImageRoute = '/og/docs';

// [!code ++:5]
export function getPageImagePath(slugs: string[], locale?: string) {
  return (
    '/' + [locale, ...docsImageRoute.split('/'), ...slugs, 'image.webp'].filter(Boolean).join('/')
  );
}
```

```tsx tab="app/routes/docs.tsx"
// [!code ++]
import { getPageImagePath } from '@/lib/shared';

// ローダー内の任意の場所で
return {
  // [!code ++]
  imagePath: getPageImagePath(page.slugs, page.locale),
};

// コンポーネントまたはクライアントローダー内の任意の場所で
return (
  <>
    {/* [!code ++] */}
    <meta property="og:image" content={imagePath} />
  </>
);
```

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

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

```tsx tab="app/routes/docs.og.tsx"
import { source } from '@/lib/source';
import { generateOGImage } from 'fumadocs-ui/og/takumi';
import type { Route } from './+types/docs.og';

export function loader({ params }: Route.LoaderArgs) {
  const slugs = params['*']
    .split('/')
    .filter((v) => v.length > 0)
    .slice(0, -1);
  const page = source.getPage(slugs);

  if (!page) throw new Response(undefined, { status: 404 });

  return generateOGImage({
    title: page.data.title,
    description: page.data.description,
    site: 'My App',
    format: 'webp',
  });
}
```

```ts tab="app/routes.ts"
import { type RouteConfig, route } from '@react-router/dev/routes';

export default [
  // [!code ++]
  route('/og/docs/*', 'routes/docs.og.tsx'),
] satisfies RouteConfig;
```

```ts tab="react-router.config.ts"
import type { Config } from '@react-router/dev/config';
import { glob } from 'node:fs/promises';
import { createGetUrl, getSlugs } from 'fumadocs-core/source';
import { getPageImagePath } from './app/lib/shared';

const getUrl = createGetUrl('/docs');

export default {
  ssr: true,
  // [!code ++:12]
  async prerender({ getStaticPaths }) {
    const paths = [...getStaticPaths()];

    for await (const entry of glob('**/*.{md,mdx}', { cwd: 'content/docs' })) {
      const slugs = getSlugs(entry);

      paths.push(getUrl(slugs));
      paths.push(getPageImagePath(slugs));
    }

    return paths;
  },
} satisfies Config;
```

> 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) を参照してください。