Skip to content

Frontend Layouts

worable edited this page Oct 12, 2026 · 1 revision

命名 Layout

Layout 是可复用的页面布局包装器。页面通过 layout 字段引用,平台负责用 Layout 组件包装页面组件。

声明 Layout

在前端清单的 layouts 数组中声明可用的 Layout 名称:

{
  "layouts": ["DefaultLayout", "SidebarLayout", "MinimalLayout"]
}

使用 Layout

页面通过 layout 字段引用:

{
  "pages": [
    {
      "path": "/blog/:slug",
      "component": "BlogPostPage",
      "layout": "DefaultLayout"
    }
  ],
  "layouts": ["DefaultLayout"]
}

页面引用的 Layout 必须在 layouts 列表中声明,否则校验失败。

Layout 组件实现

Layout 是一个 React 组件,至少接收 children 作为页面内容。平台传入的是 FrontendLayoutProps:除 children 外还有 navigation(公开导航项)、isAuthenticated、platform(平台信息)、categories(分类树,可选)、brand(logo/favicon URL,可选)和 assetsBaseUrl。

// frontend/src/index.tsx
export function DefaultLayout({ children }: FrontendLayoutProps) {
  return (
    <div className="min-h-screen">
      <header>{/* 导航 */}</header>
      <main>{children}</main>
      <footer>{/* 页脚 */}</footer>
    </div>
  );
}

export function SidebarLayout({ children }: FrontendLayoutProps) {
  return (
    <div className="flex">
      <aside>{/* 侧边栏 */}</aside>
      <main className="flex-1">{children}</main>
    </div>
  );
}

渲染机制

当页面声明了 layout 时,平台渲染流程:

<DefaultLayout>
  <BlogPostPage data={finderData} params={pathParams} />
</DefaultLayout>

如果没有声明 layout,页面组件直接渲染。

布局选择规则(apps/web/src/lib/pages.ts):

  • 主题页面:用 definition.layout 指定的主题 layout。
  • 插件页面:若当前激活主题导出了名为 theme 的 layout,则优先用它,主题掌控公开外壳;否则回退到插件 definition.layout 指定的 layout,都没有则裸渲染。

因此插件声明自己的 layout 时,激活主题仍可通过导出 theme layout 覆盖整站外观。

无 Layout

页面可以不使用 Layout(layout 字段省略)。这适用于全屏页面或自带完整布局的页面。

校验规则

  • Layout 名称在 layouts 数组中必须唯一
  • 页面引用的 Layout 必须存在于 layouts 数组中
  • layouts 在编译产物中始终存在,可为空数组 [](schema 默认 [])

Clone this wiki locally