NEXT_PUBLIC_APP_MODE 选择两种模式之一。选择是 构建时烤进去的 —— 没有运行时开关。

判定方式
apps/web/src/lib/config/app.ts 在模块加载时推导模式:
- 如果显式设了
NEXT_PUBLIC_APP_MODE→ 用它。 - 否则,如果设了
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY→cloud。 - 否则 →
self-hosted。
apps/web/src/middleware.ts 在 import 时挑对应的 middleware:
为什么用 flag,而不是两套应用?
两种模式下跑的是同一棵 React 树、同一个 store、同一组路由。再做一个独立应用只会让维护面翻倍,行为却不会增加。Flag 模式保住了:- 一个模板库
- 一个编辑器状态机
- 一套组件
加一个云端专属功能
- 在 UI 层用
APP_MODE === 'cloud'做开关(如果只针对某些自带 Clerk 的用户,用更精确的 capability flag)。 - 网络调用走
httpClient.api,让鉴权拦截器处理 token。 - 自托管下要优雅降级 —— 空状态,不要崩溃。
- 如果需要新的配置项,在 云端模式 的环境变量表里加一行。
