专门用途页面
主题可通过 theme.pagesDir 提供预设页面。主题页面遵循与用户页面一致的路由规则;若发生冲突,用户页面拥有更高优先级。
适用于承载各类“功能型页面”:
- 主题自带的落地页(Landing)
- 独立的目录/菜单页
- 友链页
- 联系页
- 主题自带的
/404页面
配置主题页面
theme/index.js:
export default () => ({
theme: {
root: '.',
pagesDir: './pages'
}
})
theme/pages/:
pages/
index.mdx
menu.mdx
friends.mdx
contact.mdx
404.mdx
基于路由的分支逻辑
若偏好“硬编码规则”,亦可基于路由进行逻辑分支:
const route = ctx.page.routePath
if (route === '/menu') { /* ... */ }
补充:目录索引页面的 routePath 均带有尾随 /(例如 /guide/)。
基于 Frontmatter 选择布局
最直观的方式是为页面添加 layout 标记,并在模板中进行差异化渲染。
示例 menu.mdx:
---
title: Menu
layout: menu
hidden: true
---
# Menu
This page uses a different layout.
模板里分支:
const MenuLayout = ({ ctx, PageContent }) => (
<div class="menu-layout">
<h1>{ctx.page.title}</h1>
<PageContent />
</div>
)
const DocLayout = ({ ctx, PageContent }) => (
<div class="doc-layout">
<aside>{/* nav */}</aside>
<main>
<PageContent />
</main>
</div>
)
export default function PageTemplate({ PageContent, ExtraHead, ctx }) {
const layout = ctx.page.frontmatter?.layout
return (
<>
<html>
<head>
<ExtraHead />
<title>{ctx.page.title || ctx.site.name}</title>
</head>
<body>
{layout === 'menu' ? (
<MenuLayout ctx={ctx} PageContent={PageContent} />
) : (
<DocLayout ctx={ctx} PageContent={PageContent} />
)}
</body>
</html>
</>
)
}
表单及交互类页面
对于联系表单等交互页面,通常可保持页面正常渲染,同时在主题 components/ 中提供 Client-only 组件(例如 ContactForm.client.jsx),供页面内容直接调用。
进阶思路:利用 .html 构建功能页
专门用途页面无需局限于 MDX。亦可在 pages/(及主题 pagesDir)下创建纯 .html 页面,用于构建独立落地页、嵌入式表单或轻量级前端应用。
此类页面将被纳入构建流程并交由 Vite 处理,同时依然经过 theme.template 渲染。通常需在模板中将其分流至“独立页面”布局:例如隐藏侧边栏/目录/页脚,或加载定制化的 <head>。
常用分流策略:
- 按文件类型:
ctx.page.filePath.endsWith('.html') - 按路由:
ctx.page.routePath === '/menu' - 按 frontmatter:
ctx.page.frontmatter?.layout === 'landing'
Base Path 与资源引用注意事项
通常无需对 theme.sources URL 及 public/ 静态文件应用 withBase() —— Methanol 构建系统会自动解析。但在 JS 中动态生成 URL 时若遇 Vite dev 路径解析不一致,withBase('/...') 仍是有效的解决方案。