Next.js 13 支持 app 和 pages 双路由共存,但官方明确建议避免混合使用——二者代表不同架构范式,混用易引发路由冲突、数据获取逻辑混乱及构建行为不可预测等问题;仅在渐进迁移或特定实验场景下可临时并存。
next.js 13 支持 `app` 和 `pages` 双路由共存,但官方明确建议**避免混合使用**——二者代表不同架构范式,混用易引发路由冲突、数据获取逻辑混乱及构建行为不可预测等问题;仅在渐进迁移或特定实验场景下可临时并存。
在 Next.js 13+ 中,app 目录(App Router)与 pages 目录(Pages Router)并非简单“功能叠加”,而是两种根本不同的应用架构模型:
- Pages Router 是传统客户端优先、页面级数据获取的模式,依赖 getServerSideProps/getStaticProps,布局需手动复用,API 路由与页面混置;
- App Router 则基于 React Server Components(RSC),默认服务端渲染,支持嵌套布局(layout.tsx)、组件级数据获取(async Server Components)、流式传输(Streaming)、以及更精细的加载/错误边界(loading.tsx, error.tsx, not-found.tsx)。
因此,即使你仅想为「动态 Sitemap 渲染」这一单一功能引入 app 目录,也需谨慎评估其技术代价:
✅ 可接受的例外场景(需严格约束)
- 处于渐进式迁移阶段:已有成熟 pages 应用,正按模块逐步迁移到 app,期间允许双目录共存,但需确保:
- 路由无重叠(如 /sitemap 在 app/sitemap/page.tsx,而 pages/sitemap.tsx 必须删除);
- 共享逻辑(如 API 客户端、类型定义)统一抽离至 lib/ 或 src/ 根目录,避免重复实现;
- 构建配置(如 next.config.js)兼容双模式,禁用可能冲突的插件(如旧版 next-images)。
❌ 不推荐的实践(即问题中描述的情形)
- 仅为单个功能(如 Sitemap)单独启用 app 目录,其余全部保留在 pages —— 这违背 App Router 的设计初衷,且带来以下风险:
- Sitemap 无法真正“动态”:若 app/sitemap/page.tsx 依赖客户端状态或未正确使用 fetch(..., { cache: 'no-store' }),仍可能被静态缓存;
- 构建产物分裂:Next.js 将分别处理两个目录,可能导致 chunk 命名冲突、公共依赖重复打包;
- 开发体验割裂:use client、RSC 边界、server-only 检查等规则仅对 app 生效,却需开发者在项目中频繁切换心智模型。
? 更优替代方案
对于动态 Sitemap,无需引入 app 目录即可在 pages 中高质量实现:
// pages/sitemap.xml.ts
import { getServerSideProps } from 'next';
import { generateSitemapXml } from '@/lib/sitemap';
export default function Sitemap() {
return null; // 此页面不渲染 UI
}
export const getServerSideProps = async () => {
const xml = await generateSitemapXml(); // 动态查询数据库或 CMS
return {
props: {},
// 直接返回 XML 响应
headers: { 'Content-Type': 'application/xml' },
// 关键:禁用缓存以确保实时性
revalidate: 60, // ISR:每分钟重新生成
};
};
⚠️ 注意:pages/sitemap.xml.ts 会自动映射为 /sitemap.xml 路由,并支持 SSR + ISR,完全满足动态需求,且零额外架构成本。
? 总结建议
- ✅ 新项目:直接采用 app 目录,拥抱 Server Components、嵌套布局与流式渲染;
- ✅ 存量 pages 项目:制定清晰迁移路线图(如先迁移 Layout → 再迁移关键页面 → 最后迁移 API),而非“打补丁式”混用;
- ❌ 禁止:为单一功能开启 app 目录,同时长期保留 pages 主体——这既未获得 App Router 的核心收益(如减少客户端 JS、状态保持),又承担了双模式维护成本。
官方文档明确指出:“The app and pages directories can co-exist, but they are not designed to be used together in the same application for production.”(Next.js Docs, App Router Overview)——请以架构一致性为优先,而非功能便利性。











