You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:01:11