Next.js 15迁移Sanity CMS数据缓存失效问题求助
在Next.js 15中配置Sanity数据获取的缓存策略
Next.js 15默认缓存策略改为「默认无缓存」,导致原有Sanity数据获取逻辑不再自动缓存,需手动指定缓存规则。以下是几种可行的解决方案:
方案1:在单个fetch调用中指定缓存配置
直接在client.fetch的第三个参数中添加Next.js缓存选项,针对特定查询设置缓存策略:
修改sanity-query.ts中的函数:
export async function getExperiences(language: string) { return client.fetch( groq`*[_type == "experience" && language == $language] | order(endDate desc){ name, company, "logo": logo.asset->url, url, description, city, province, startDate, endDate }`, { language }, { next: { revalidate: 3600 } // 缓存1小时后自动重新验证 // 或者使用强制缓存:cache: 'force-cache' } ); } export async function getSkills() { return client.fetch( groq`*[_type == "skill"] | order(_createdAt desc){ localizedName, skills[]{ name, "logo": logo.asset->url, "darklogo": darklogo.asset->url, url } }`, {}, { next: { revalidate: 3600 } } ); }
revalidate: 3600:设置缓存有效期为1小时,到期后Next.js会在后台重新获取数据并更新缓存。cache: 'force-cache':和Next.js 14默认行为一致,强制缓存数据,直到手动刷新或revalidateTag触发更新。
方案2:全局配置Sanity Client的缓存策略
如果希望所有Sanity查询都应用统一的缓存规则,可以在创建client时设置fetchOptions:
修改client.ts:
import { createClient } from 'next-sanity'; import { apiVersion, dataset, projectId } from '../env'; const client = createClient({ projectId, dataset, apiVersion, useCdn: true, fetchOptions: { next: { revalidate: 3600 } // 全局应用1小时缓存有效期 // 或者 cache: 'force-cache' }, }); export default client;
所有通过该client发起的fetch请求都会自动继承这个缓存配置,无需在每个查询中重复设置。
方案3:组件级缓存配置(Server Component适用)
如果你的CodingSkills是Server Component,可以直接在组件文件中添加revalidate配置,控制整个组件的缓存有效期:
修改Skills.ts:
import { getSkills } from "@/sanity/sanity-query"; import { SkillsType } from "@/types"; // 设置组件缓存有效期为1小时 export const revalidate = 3600; const CodingSkills = async () => { const skills: SkillsType[] = await getSkills(); return ( <> <Skills codingSkills={skills} /> </> ); }; export default CodingSkills;
这种方式会将组件及其依赖的数据一起缓存,适合组件与数据生命周期一致的场景。
额外优化:使用缓存标签实现细粒度刷新
如果需要手动刷新特定数据的缓存,可以在缓存配置中添加tags,后续通过revalidateTag API触发更新:
例如在getSkills中设置标签:
export async function getSkills() { return client.fetch( groq`*[_type == "skill"] | order(_createdAt desc){...}`, {}, { next: { revalidate: 3600, tags: ['skills'] } } ); }
之后在API路由或服务器端函数中调用:
import { revalidateTag } from 'next/cache'; export async function POST() { revalidateTag('skills'); return Response.json({ success: true }); }
这样就能精准刷新技能数据的缓存,而不影响其他内容。
内容的提问来源于stack exchange,提问作者SpicyyRiice
相关产品推荐
相关产品推荐

