> For AI agents: the complete documentation index is available at https://rspress.rs/zh/llms.txt, the full documentation bundle is available at https://rspress.rs/zh/llms-full.txt.

# 自定义页面

Rspress 提供了多种方式能让你自定义页面的内容，包括：

- 添加自定义全局组件；
- 添加自定义全局样式；
- 自定义页面布局结构。

## 自定义全局组件

某些场景下，你可能需要在页面中添加一些自定义的全局组件，Rspress 提供了一个配置项 `globalUIComponents` 来实现这个功能。

### 使用方法

在 `rspress.config.ts` 中添加以下配置：

```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import path from 'path';

export default defineConfig({
  globalUIComponents: [path.join(__dirname, 'components', 'MyComponent.tsx')],
});
```

`globalUIComponents` 的每一项可以是一个字符串，代表组件的文件路径；也可以是一个数组，第一项为组件的文件路径，第二项为组件的 props 对象，比如：

```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';

export default defineConfig({
  globalUIComponents: [
    [
      path.join(__dirname, 'components', 'MyComponent.tsx'),
      {
        foo: 'bar',
      },
    ],
  ],
});
```

当你注册了全局组件之后，Rspress 会自动将这些 React 组件在主题中进行渲染，而不用你手动引入。

通过全局组件，你可以完成诸多自定义的功能，比如:

```tsx title="compUi.tsx"
import React from 'react';

// 需要默认导出一个组件
// 通过 props 来拿到配置中传入的 props 数据
export default function PluginUI(props?: { foo: string }) {
  return <div>This is a global layout component</div>;
}
```

这样，在主题页面中会渲染组件的内容，比如添加**回到顶部按钮**。

同时，你也可以通过全局组件来注册全局副作用。比如：

```tsx title="compSideEffect.tsx"
import { useEffect } from 'react';
import { useLocation } from '@rspress/core/runtime';

// 需要默认导出一个组件
export default function PluginSideEffect() {
  const { pathname } = useLocation();
  useEffect(() => {
    // 组件初次渲染时执行
  }, []);

  useEffect(() => {
    // 路由变化时执行
  }, [pathname]);
  return null;
}
```

这样，在主题页面中会执行组件的副作用。比如以下的一些需要副作用的场景:

- 针对某些页面路由进行重定向操作。
- 对页面的 img 标签进行事件监听，实现图片放大功能。
- 路由变化时，上报不同页面的 PV 数据。
- ......

## 自定义布局结构

Rspress 提供了 `pageType` 配置来让你自定义页面的布局结构。

### 使用 pageType

Rspress 的约定式路由支持了两种路由，一种是文档路由，即用 md(x) 文件编写的页面，另一种是组件路由，即 `.jsx/.tsx` 文件编写的页面。

对于前者，你可以在 frontmatter 中添加 `pageType` 字段来指定页面的布局结构，比如：

```mdx title="foo.mdx"
---
pageType: custom
---
```

对于后者，你可以添加如下的导出来指定 `pageType`：

```tsx title="foo.tsx"
// 导出 frontmatter 对象，其含义与 md(x) 文件中的 frontmatter 一致
export const frontmatter = {
  // 声明布局类型
  pageType: 'custom',
};
```

pageType 可以配置为如下的值：

- `home`: **首页**，包含顶部导航栏和首页的布局内容。
- `doc`: **文档页**，包含顶部导航栏、左边侧边栏、正文内容和右侧的大纲栏。
- `doc-wide`: **宽屏文档页**，配合 `outline: false` 和 `sidebar: false` 设置时，正文内容会自动占据更宽的屏幕空间。
- `custom`: **自定义页面**，包含顶部导航栏和自定义的内容。
- `blank`: 也属于**自定义页面**，但是不包含`顶部导航栏`。
- `404`: **404 页面**。

### 使用细粒度开关

除了 `pageType` 页面布局级别的配置之外，Rspress 还提供了更细粒度的开关，你可以在 frontmatter 配置其它的字段，这些字段及其含义如下：

- `navbar`：是否展示顶部导航栏，当你想要隐藏顶部导航栏时，可以配置为 `false`；
- `sidebar`：是否展示侧边栏，当你想要隐藏侧边栏时，可以配置为 `false`；
- `outline`：是否展示大纲栏，当你想要隐藏大纲栏时，可以配置为 `false`；
- `footer`：是否展示页脚，当你想要隐藏页脚时，可以配置为 `false`；
- `globalComponents`: 是否展示全局组件，当你想要隐藏全局组件时，可以配置为 `false`。

示例：

```mdx title="foo.mdx"
---
navbar: false
sidebar: false
outline: false
footer: false
globalUIComponents: false
---
```
