基于Sanity schemaTypes构建Next.js路由:选路由组还是动态路由?
基于Sanity Schema的Next.js路由设计与内容同步方案
一、正确的路由结构选择
不要用动态路由,路由组可用于代码组织,但核心必须遵循Next.js路由约定
1. 首页(对应Sanity home 单例)
直接使用 app/page.tsx,Next.js 中该文件默认对应根路径 /。若想把首页相关代码(组件、工具函数等)分组管理,可使用路由组 (home),结构如下:
/app (home) page.tsx # 对应根路径 / not-found.tsx [slug] page.tsx
路由组仅用于代码归类,不会改变URL结构,(home)/page.tsx 依然对应 /。
2. 错误页(对应Sanity error 单例)
Next.js 有专门的404页面约定:app/not-found.tsx,访问不存在的路由时会自动渲染该文件。你需要在这个文件中获取Sanity error 单例的内容,不要用(error)路由组或[error]动态路由——后者会生成/error这样的URL,不符合404页的触发逻辑。
3. 动态页面(对应Sanity page 文档)
使用 app/[slug]/page.tsx,通过slug参数从Sanity获取对应页面的数据。若要分组管理动态页面代码,也可嵌套路由组:
/app page.tsx not-found.tsx (page) [slug] page.tsx # 对应 /[slug]
二、Sanity内容修改后同步更新前端的实现
1. 增量静态再生(ISR)
在页面组件中设置revalidate属性,让Next.js定期重新获取数据并更新页面:
// app/page.tsx export const revalidate = 60; // 每60秒重新生成页面 async function getHomeData() { // 从Sanity获取home单例数据的逻辑 } export default async function Home() { const homeData = await getHomeData(); return <div>{/* 渲染首页内容 */}</div>; }
2. Sanity Webhook + 主动触发重新生成
在Sanity后台配置Webhook,内容修改时调用Next.js的重验证API,实时更新对应页面:
- 创建
app/api/revalidate/route.ts:
import { revalidatePath } from 'next/cache'; import { NextResponse } from 'next/server'; export async function POST(request: Request) { // 建议验证Sanity Webhook签名,避免恶意请求 const body = await request.json(); const slug = body.slug?.current; switch(body._type) { case 'home': revalidatePath('/'); break; case 'error': revalidatePath('/not-found'); break; case 'page': if(slug) revalidatePath(`/${slug}`); break; } return NextResponse.json({ revalidated: true }); }
- 在Sanity后台添加Webhook,指向该API的部署URL,触发条件设为「文档创建/更新/删除」。
3. 实时预览(可选)
配置Sanity预览模式,结合Next.js的预览功能,在Sanity编辑器中实时查看前端效果,无需等待页面重新生成。
三、对你当前思路的修正
[home]/[error]动态路由是错误的:动态路由会将参数作为URL的一部分(如/home),不符合首页根路径、404自动触发的需求。- 路由组的使用是可行的,但仅作为代码组织手段,核心必须遵循Next.js的路由约定(
page.tsx对应路径、not-found.tsx对应404)。
内容的提问来源于stack exchange,提问作者GʀᴜᴍᴘʏCᴀᴛ
相关产品推荐
相关产品推荐

