Fumadocs

访问控制

限制内容访问。

概览

🌐 Overview

得益于灵活的设计,使用 Fumadocs 实现访问控制非常简单。

🌐 Thanks to the flexible design, it is simple to implement access control with Fumadocs.

加载器 API

🌐 Loader API

如果你正在使用 loader() API,你可以按需创建加载器,并从内容来源中过滤文件以限制可访问的内容。

🌐 If you are using loader() API, you can create the loaders on-demand, and filter files from content source to restrict accessible content.

例如,这种使用 Fumadocs MDX 的设置仅允许显示带有前置内容 permission: public 的 MDX 文件。

🌐 For example, this setup with Fumadocs MDX allows only MDX files with frontmatter permission: public to be shown.

lib/source.ts
import { docs } from 'fumadocs-mdx:collections/server';
import { loader, update } from 'fumadocs-core/source';

const filteredSource = update(docs.toFumadocsSource())
  .files((files) =>
    files.filter((file) => {
      // keep meta files (e.g. `meta.json`)
      if (file.type === 'meta') return true;

      // access file data (type-safe)
      return file.data.permission === 'public';
    }),
  )
  .build();

export const source = loader(filteredSource, {
  baseUrl: '/docs',
});

或者在更复杂的设置下,你可以将 source 转换为一个工厂函数。

🌐 Or with more complicated setup, you may turn source into a factory function.

import { docs } from 'fumadocs-mdx:collections/server';
import { loader, update } from 'fumadocs-core/source';

// uncached, it's better to cache it in-memory for real use case.
export function createSource(permission: 'public' | 'admin') {
  const filteredSource = update(docs.toFumadocsSource())
    .files((files) =>
      files.filter((file) => {
        if (file.type === 'meta') return true;

        return file.data.permission === permission;
      }),
    )
    .build();

  return loader(filteredSource, {
    baseUrl: '/docs',
  });
}

优势

🌐 Advantages

这个方法的特别之处在于访问限制是在输入层面,而不是在渲染阶段或构建时。

🌐 What is special with this approach is that the access is limited at input level, rather than at rendering phase or build-time.

这保证了受保护的内容被完全过滤,同时灵活性不受影响。

🌐 This guarantees the protected content is filtered entirely, and without compromise on flexibility.

自定义实现

🌐 Custom Implementation

不使用 Loader API,你也可以在框架层面实现访问控制(例如,通过 Next.js 路由和代理)。

🌐 Without using Loader API, you can also implement your access control at framework-level (e.g. via Next.js routing & proxy).

例如,要限制对某些页面的访问:

🌐 For example, to limit access to certain pages:

page.tsx
import { notFound } from 'next/navigation';
import { source } from '@/lib/source';

export default async function Page({ params }) {
  const { slugs } = await params;
  const user = await getUser();
  const page = source.getPage(slugs);

  if (!page) notFound();
  if (page.data.permission !== user.permission) notFound();

  // render page...
}

请注意,管理页面树(侧边栏项目)、搜索和其他细节由你自行负责。

🌐 Note that it is up to you to manage the page tree (sidebar items), search and other details.

这种方法提供了最佳的灵活性,但它本身不依赖 Fumadocs 进行访问控制,设置可能需要更长时间且更复杂。

🌐 This approach offers the best flexibility, but it doesn't rely on Fumadocs itself for access control, the setup may take longer and be more complicated.

在实现时,最好查阅你所使用的 React.js 框架的文档。

🌐 It is better to consult the docs of your React.js framework when implementing.

Last updated on

On this page