跳至內容
Fumadocs

瀏覽器入口

從瀏覽器/用戶端環境存取集合。

使用 Macro API?

巨集集合可直接在用戶端匯入,無需用戶端載入器。對應的用法請參閱 Macro API。

使用方式

產生的輸出已使用非同步匯入,針對瀏覽器環境進行最佳化。

在瀏覽器中只能存取 doc/docs 集合。

import browserCollections from 'collections/browser';

// 尚未載入的項目
console.log(browserCollections['collection name'].raw);

// 定義用戶端集合載入器
const clientLoader = browserCollections['collection name'].createClientLoader({
  component(
    // 存取已編譯的檔案
    { default: MDX },
    // 定義 props(選用)
    props: { myProp: string },
  ) {
    return (
      <div>
        <MDX />
      </div>
    );
  },
});

// 由伺服器(靜態產生器)回傳路徑
async function serverLoader() {
  return source.getPage(slugs)!.path;
}

async function loader() {
  const path = await serverLoader();
  // 預先載入此路徑
  await clientLoader.preload(path);
  return { path };
}

function Page() {
  const { path } = loader();

  // 算繪內容
  return clientLoader.useContent(path, {
    myProp: 'hello world',
  });
}

路徑參數

若頁面使用路徑參數,請在路徑後方傳入對應的參數:

async function serverLoader() {
  const page = source.getPage(slugs)!;
  return { path: page.path, params: page.params };
}

async function loader() {
  const { path, params } = await serverLoader();
  await clientLoader.preload(path, params);
  return { path, params };
}

function Page() {
  const { path, params } = loader();

  return clientLoader.useContent(path, { myProp: 'hello world' }, params);
}

範例

以下範例適用於在 React Router 與 TanStack Start 上不使用 RSC 的情況。若使用 Next.js 或 Waku,建議改用 RSC 搭配 server entry,以獲得更好的用戶端效能。

我們儲存庫中的範例應用程式則改用 Macro API 來處理這部分,很適合作為完整設定的參考。

app/routes/docs.tsx
import type { Route } from './+types/docs';
import { source } from '@/lib/source';
import browserCollections from 'collections/browser';

export async function loader({ params }: Route.LoaderArgs) {
  const slugs = params['*'].split('/').filter((v) => v.length > 0);
  const page = source.getPage(slugs);
  if (!page) throw new Response('Not found', { status: 404 });

  return {
    path: page.path,
  };
}

const clientLoader = browserCollections.docs.createClientLoader({
  component({ frontmatter, default: MDX }) {
    return (
      <div className="prose">
        <h1>{frontmatter.title}</h1>
        <MDX />
      </div>
    );
  },
});

export default function Page(props: Route.ComponentProps) {
  const { path } = props.loaderData;

  return clientLoader.useContent(path);
}

How is this guide?

最後更新於