export const myPage = siteDocumentSchema.parse({
slug: 'my-page',
path: '/my-page',
title: 'My Page',
description: 'Structured content with a switchable skin.',
privacy: 'private',
defaultTheme: 'noir',
themeOptions: ['noir', 'paper', 'frame'],
hero: {
eyebrow: 'PRIVATE ROUTE',
title: 'Title',
subtitle: 'Role / Signal / Positioning',
body: 'Keep copy here, not in the renderer.',
tags: ['Schema First', 'Theme Switchable'],
actions: [{ label: 'Open Styles', href: '/styles' }],
stats: [{ label: 'Themes', value: '3' }]
},
sections: [],
footer: { note: 'schema + theme + renderer', links: [] }
});schema 的职责不是描述视觉,而是描述页面的事实结构
John Ousterhout 的做法是让每层只承担单一职责。这个 schema 就只负责内容形状、section 顺序和链接关系,不负责皮肤和实现细节。
一个完整页面的三段式骨架
document object、thin route、host rewrite 现在分别承担三段职责。
export default async function Page({
searchParams,
}: {
searchParams?: Promise<Record<string, string | string[] | undefined>>;
}) {
const params = (await Promise.resolve(searchParams)) ?? {};
const theme = Array.isArray(params.theme) ? params.theme[0] : params.theme;
return <SiteRenderer document={myPage} themeId={theme} />;
}export function middleware(request: NextRequest) {
const host = request.headers.get('host') ?? '';
if (host.includes('styles.zondev.top')) {
return rewrite('/styles' + request.nextUrl.pathname);
}
}当前支持的 section kinds
这套 catalog 现在已经覆盖 intro / hiring / docs / proof / CTA 几类常见页面。以后先问能否复用这些 kind,再决定是否扩新的。
用于长段叙事、方法说明、定位解释。
Narrative section
当你需要用完整句子说清楚思路时。
这类 section 适合表达判断、方法和上下文,而不是离散卡片。
如果只是几个要点,就不要硬塞 narrative,用 cards 或 metrics 会更清楚。
用于并排呈现几个强信号或关键数字。
Metrics section
用于 feature、proof、problem-decision-impact 这类离散内容。
Cards section
手工堆页面
页面一多就会越来越散。
统一 schema
先稳定结构和边界。
复用更便宜
以后更多时间花在内容,不花在重复排版。
用于经历、版本演进、迭代过程。
Timeline section
Manual
先做出一个可用版本。
- 验证方向
- 暴露维护问题
Structured
把页面升级成 schema + theme + renderer。
- 开始有复用
- 开始有 docs
用于 playbook、操作流程、生产顺序。
Steps section
Write data
先写 document 和 section 顺序。
Pick theme
再决定皮肤,不复制 route。
Render
最后才让 route 负责装配。
用于原则、结论、判断标准。
Quote section
先让内容可迁移,再让视觉可升级。
用于联系方式、入口页、下一步动作。
用于 before/after、旧方案/新方案、A/B 对照。
Comparison section
散在 route 和 JSX 里。
集中在 data object 里。
靠复制页面切明暗。
靠 theme token 切明暗。
用于 docs 常见问题、招聘方疑问、使用说明。
FAQ section
什么时候该扩 section kind?OPEN
当结构真的不同,而不是 copy 变化时。
什么时候只要换 data?OPEN
当页面骨架不变,只是内容、顺序或链接变化时。
用于 CTA、结论强化、章节转场。
只有结构变化,才值得新增 kind
如果只是内容不同、主题不同、顺序不同,那都应该继续落回 data 或 theme。 新增 kind 的门槛要高,否则 schema 很快会退化成“页面版本列表”。