# Fumadocs (Framework Mode, React Router): Takumi
URL: /zh-TW/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.zh-TW.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';

// 在您的 loader 中的某處
return {
  // [!code ++]
  imagePath: getPageImagePath(page.slugs, page.locale),
};

// 在您的元件或用戶端 loader 中的某處
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 範本](https://takumi.kane.tw/docs/templates)。