Next.js App Router (Deep Workflow)
App Router changes mental models: where code runs, what is cached, and how HTML streams. Defaults differ from Pages Router—call that out explicitly.
When to Offer This Workflow
Trigger conditions:
- - New App Router project or migration from pages/
- Confusion Server vs Client Components; hooks errors
- Stale data, wrong cache, need ISR semantics
Initial offer:
Use six stages: (1) route & layout model, (2) Server vs Client boundaries, (3) data fetching & cache, (4) revalidation & tags, (5) streaming & UX, (6) deployment & runtime. Confirm Next version and hosting (Vercel self, etc.).
Stage 1: Route & Layout Model
Goal: app/ directory = nested layouts + col ocated routes.
Practices
- -
layout.tsx for shared UI and providers (client where needed) page.tsx is leaf UI per segmentloading.tsx, error.tsx, not-found for UX boundaries
Exit condition: URL tree matches folder tree mental model.
Stage 2: Server vs Client Components
Goal: Default Server Components; use client only where interactivity needs browser APIs or state.
Rules of thumb
- - Data fetch on server by default (async components)
- Leaf interactive islands as client components
- Prop serialization: only JSON-serializable props across boundary
Exit condition: List of client components and why.
Stage 3: Data Fetching & Cache
Goal: fetch cache semantics (force-cache vs no-store vs revalidate) explicit per call.
Practices
- - Align with auth: no-store or request memoization patterns for user-specific data
- Parallel fetch where possible to avoid waterfalls
Exit condition: Per-route data dependency graph (simple diagram).
Stage 4: Revalidation & Tags
Goal: Fresh when needed without DDOS origin.
Practices
- -
revalidatePath / revalidateTag from server actions or route handlers - Webhook-triggered revalidation for CMS
Exit condition: Invalidation owner and trigger documented.
Stage 5: Streaming & UX
Goal: Suspense boundaries with meaningful fallbacks; a11y for loading.
Practices
- - Avoid waterfall inside suspense trees (sequential awaits)
Stage 6: Deployment & Runtime
Goal: Node vs edge runtime per route segment when using edge.
Practices
- - Edge cannot use all Node APIs—verify compat
- ISR on serverless may need warming or cron revalidate
Final Review Checklist
- - [ ] Layouts and route segments match product IA
- [ ] Server/Client split justified; props serializable
- [ ] Fetch cache and auth story correct per route
- [ ] Revalidation path defined for CMS/dynamic data
- [ ] Streaming/suspense without accidental waterfalls
- [ ] Runtime (edge vs node) matches dependencies
Tips for Effective Guidance
- - Refer to current Next.js docs for default fetch caching — defaults changed across versions.
- Middleware for auth redirects — mind matcher performance.
- Colocation of tests and Storybook for client components helps isolation.
Handling Deviations
- - Pages Router legacy: map equivalents (getServerSideProps → async RSC) carefully.
- Turbopack / Webpack — different perf profiles in dev.
Next.js App Router(深度工作流)
App Router 改变了 心智模型:代码 在哪里 运行、什么 被 缓存、以及 HTML 如何 流式传输。默认行为 与 Pages Router 不同——请 明确 指出 这一点。
何时提供此工作流
触发条件:
- - 新的 App Router 项目 或 从 pages/ 迁移
- 对 服务端 与 客户端 组件 感到困惑;出现 hooks 错误
- 数据 过时、缓存 错误、需要 ISR 语义
初始提供:
使用 六个阶段:(1) 路由与布局模型,(2) 服务端与客户端边界,(3) 数据获取与缓存,(4) 重新验证与标签,(5) 流式传输与用户体验,(6) 部署与运行时。确认 Next 版本 和 托管方式 (Vercel 自托管 等)。
阶段 1:路由与布局模型
目标: app/ 目录 = 嵌套布局 + 共置路由。
实践
- - layout.tsx 用于 共享 UI 和 提供者 (需要时 使用 客户端)
- page.tsx 是 每个 路径段 的 叶子 UI
- loading.tsx、error.tsx、not-found 用于 用户体验 边界
退出条件: URL 树 与 文件夹 树 心智模型 匹配。
阶段 2:服务端与客户端组件
目标: 默认 使用 服务端组件;仅在 需要 浏览器 API 或 状态 的 交互 场景 使用 use client。
经验法则
- - 默认 在 服务端 获取 数据 (异步 组件)
- 将 叶子 交互 岛屿 作为 客户端 组件
- 属性 序列化:仅 跨 边界 传递 JSON 可序列化 属性
退出条件: 列出 客户端 组件 及其 原因。
阶段 3:数据获取与缓存
目标: 每个 调用 明确 指定 fetch 缓存 语义 (force-cache 与 no-store 与 revalidate)。
实践
- - 与 认证 对齐:对于 用户特定 数据 使用 no-store 或 请求 记忆化 模式
- 尽可能 并行 获取 数据 以避免 瀑布 效应
退出条件: 每个 路由 的 数据 依赖 图 (简单 图表)。
阶段 4:重新验证与标签
目标: 在 需要时 保持 数据 新鲜 而 不 对 源 服务器 造成 DDOS 攻击。
实践
- - 从 服务端 操作 或 路由 处理程序 调用 revalidatePath / revalidateTag
- 为 CMS 使用 Webhook 触发的 重新验证
退出条件: 记录 失效 的 所有者 和 触发器。
阶段 5:流式传输与用户体验
目标: 使用 有意义的 后备内容 的 Suspense 边界;为 加载 状态 提供 无障碍 支持。
实践
- - 避免 在 suspense 树 内部 出现 瀑布 效应 (顺序 await)
阶段 6:部署与运行时
目标: 当 使用 边缘 运行时 时,每个 路由 段 选择 Node 与 边缘 运行时。
实践
- - 边缘 运行时 无法 使用 所有 Node API——请 验证 兼容性
- 在 无服务器 环境 中的 ISR 可能 需要 预热 或 定时 重新验证
最终审查清单
- - [ ] 布局和路由段与产品信息架构匹配
- [ ] 服务端/客户端拆分合理;属性可序列化
- [ ] 每个路由的获取缓存和认证逻辑正确
- [ ] 为CMS/动态数据定义了重新验证路径
- [ ] 流式传输/suspense没有意外的瀑布效应
- [ ] 运行时(边缘与Node)与依赖项匹配
有效指导技巧
- - 参考 当前 Next.js 文档 了解 默认 fetch 缓存 行为——默认值 在 不同 版本 间 有 变化。
- 使用 中间件 进行 认证 重定向——注意 匹配器 性能。
- 将 测试 和 Storybook 与 客户端 组件 共置 有助于 隔离。
处理偏差
- - Pages Router 遗留 代码:仔细 映射 等价 功能 (getServerSideProps → 异步 RSC)。
- Turbopack / Webpack —— 在 开发 环境 中 具有 不同 的 性能 特征。