Skip to content

路由重写

VitePress 提供了强大的路由重写功能,允许你自定义源文件到 URL 路径的映射关系。这对于重构文档结构、保持旧 URL 兼容性、组织多语言内容等场景非常有用。

基本概念

什么是路由重写?

路由重写允许你将源文件的物理路径映射到不同的 URL 路径。例如:

源文件路径                    URL 路径
docs/guide/getting-started → /guide/introduction
docs/api/v1/users.md       → /api/users

为什么需要路由重写?

场景说明
文档重构移动文件但保持旧 URL 可访问
多版本文档不同版本的文档使用不同的 URL 前缀
多语言站点为不同语言分配不同的路径前缀
URL 美化将深层目录结构映射为简洁的 URL

配置方式

rewrites 选项

在配置文件中使用 rewrites 选项:

ts
// docs/.vitepress/config.mts
export default defineConfig({
  rewrites: {
    // 简单重写
    'guide/getting-started.md': 'guide/introduction.md',
    
    // 使用通配符
    'api/v1/:path': 'api/:path',
    
    // 多级目录重写
    'docs/:section/:sub/:page': ':section/:sub/:page'
  }
})

重写规则语法

精确匹配

ts
rewrites: {
  // 将旧路径映射到新路径
  'old-path.md': 'new-path.md',
  'guide/old-name.md': 'guide/new-name.md'
}

通配符匹配

使用 :name 语法定义动态段:

ts
rewrites: {
  // :path 匹配任意路径
  'v1/:path': ':path',
  
  // 多个动态段
  ':lang/guide/:page': 'guide/:lang/:page'
}

通配符后缀

使用 * 匹配剩余路径:

ts
rewrites: {
  // 匹配 docs/ 下的所有文件
  'docs/**': ':path*',
  
  // 保留目录结构
  'src/**': 'docs/:path*'
}

实际应用场景

场景一:文档重构

将旧版文档迁移到新结构,同时保持旧 URL 可访问:

ts
export default defineConfig({
  rewrites: {
    // 旧版路径 → 新版路径
    'getting-started.md': 'guide/introduction.md',
    'installation.md': 'guide/installation.md',
    'configuration.md': 'reference/config.md',
    
    // 批量重写
    'old-api/:name.md': 'api/:name.md'
  }
})

场景二:多语言文档

为不同语言版本配置不同的 URL 前缀:

ts
export default defineConfig({
  rewrites: {
    // 英文文档保持默认路径
    // docs/guide.md → /guide
    
    // 中文文档添加 /zh 前缀
    'zh/:path': 'zh/:path'
    // docs/zh/guide.md → /zh/guide
  },
  
  locales: {
    root: { label: 'English', lang: 'en' },
    zh: { label: '简体中文', lang: 'zh-CN' }
  }
})

场景三:版本化文档

管理多版本文档的 URL 结构:

ts
export default defineConfig({
  rewrites: {
    // 当前版本(最新)
    'current/:path': ':path',
    
    // 历史版本
    'v1/:path': 'v1/:path',
    'v2/:path': 'v2/:path'
  }
})

场景四:源文件组织

将源文件组织在子目录中,但生成扁平的 URL:

ts
export default defineConfig({
  rewrites: {
    // 源文件在 docs/content/guide/*.md
    // URL 为 /guide/*
    'content/guide/:page': 'guide/:page',
    
    // API 文档
    'content/api/:name': 'api/:name'
  }
})

高级用法

动态重写

使用函数动态计算重写规则:

ts
import { defineConfig } from 'vitepress'

export default defineConfig({
  rewrites: Object.fromEntries(
    // 自动将 docs/*.md 映射到根路径
    ['index', 'getting-started', 'guide'].map(name => [
      `${name}.md`,
      name === 'index' ? 'index.md' : `${name}.md`
    ])
  )
})

结合 cleanUrls

cleanUrls 配合使用:

ts
export default defineConfig({
  // 启用清洁 URL(移除 .html 后缀)
  cleanUrls: true,
  
  rewrites: {
    // URL 将显示为 /guide/introduction 而非 /guide/introduction.html
    'guide/intro.md': 'guide/introduction.md'
  }
})

重定向配置

重写只影响构建输出路径,不会创建重定向。如需重定向旧 URL,需要配置:

ts
// docs/.vitepress/config.mts
export default defineConfig({
  rewrites: {
    'old-path.md': 'new-path.md'
  },
  
  // 使用 head 配置添加重定向 meta 标签
  head: [
    // 在旧页面添加重定向(需要单独维护旧页面)
    ['meta', { 'http-equiv': 'refresh', content: '0; url=/new-path' }]
  ]
})

注意事项

构建时处理

重要提示

重写规则在构建时生效,不会改变源文件的位置。源文件仍然按照原有目录结构组织。

相对链接

重写后,Markdown 中的相对链接需要更新:

markdown
<!-- 重写前 -->
[安装指南](./installation.md)

<!-- 重写后(如果 installation.md 被重写为 guide/install.md)-->
[安装指南](/guide/install)

静态资源

静态资源路径不受重写影响,仍相对于 public 目录:

public/
  images/
    logo.png    → /images/logo.png(不受重写影响)

与路由冲突

确保重写规则不会导致路由冲突:

ts
// ❌ 错误:两个源文件映射到同一 URL
rewrites: {
  'guide/intro.md': 'guide/index.md',
  'guide/overview.md': 'guide/index.md'  // 冲突!
}

// ✅ 正确:每个源文件映射到唯一 URL
rewrites: {
  'guide/intro.md': 'guide/introduction.md',
  'guide/overview.md': 'guide/overview.md'
}

完整示例

项目文档站重写配置

ts
// docs/.vitepress/config.mts
import { defineConfig } from 'vitepress'

export default defineConfig({
  // 清洁 URL
  cleanUrls: true,
  
  // 路由重写
  rewrites: {
    // 首页
    'index.md': 'index.md',
    
    // 指南文档扁平化
    'content/guide/:page': 'guide/:page',
    
    // API 文档保持结构
    'content/api/:section/:name': 'api/:section/:name',
    
    // 多语言
    'locales/zh/:path': 'zh/:path',
    'locales/en/:path': 'en/:path',
    
    // 版本化
    'versions/next/:path': 'next/:path',
    'versions/v1/:path': 'v1/:path'
  },
  
  // 多语言配置
  locales: {
    root: { label: '简体中文', lang: 'zh-CN' },
    en: { label: 'English', lang: 'en-US' }
  }
})

目录结构示例

docs/
├── .vitepress/
│   └── config.mts
├── content/
│   ├── guide/
│   │   ├── index.md        → /guide
│   │   ├── getting-started → /guide/getting-started
│   │   └── configuration   → /guide/configuration
│   └── api/
│       ├── index.md        → /api
│       └── methods/
│           └── fetch.md    → /api/methods/fetch
├── locales/
│   ├── zh/                 → /zh/*
│   └── en/                 → /en/*
└── index.md                → /

调试技巧

查看重写结果

使用 vitepress build 并检查输出目录:

bash
npm run docs:build
ls -la docs/.vitepress/dist/

开发服务器验证

启动开发服务器检查 URL 是否正确:

bash
npm run docs:dev
# 访问 http://localhost:5173/your-rewritten-path

构建日志

启用详细日志查看重写过程:

ts
// vite.config.ts(如果使用自定义 Vite 配置)
export default {
  build: {
    rollupOptions: {
      onwarn(warning, warn) {
        console.log('Rewrite:', warning)
        warn(warning)
      }
    }
  }
}

最佳实践

实践说明
保持简单避免过于复杂的重写规则,增加维护难度
文档注释在配置文件中添加注释说明重写目的
定期清理移除不再需要的旧重写规则
测试覆盖确保所有重写路径都有对应的测试
保持一致团队内统一重写规则命名约定

相关资源

贡献者

加载中...

想要成为贡献者?

在 CNB 上参与贡献