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

NextJS使用ApolloClient调用Sanity GraphQL无法查询ID含点的文档

问题原因

  1. 权限缺失:你在浏览器中使用Sanity GraphQL Playground时,由于你已经登录了Sanity管理后台,浏览器会自动携带你的账号凭证发起请求,因此可以获取到所有文档,包括草稿(drafts.前缀)和本地化衍生文档(i18n.前缀)。而前端Apollo Client发起请求时未携带授权凭证,Sanity API默认只会返回不需要权限的公开发布基础文档,也就是你看到的_id不带点的内容。
  2. 缓存主键冲突:如果添加凭证后仍然出现带点_id的文档丢失,是因为Apollo Client的InMemoryCache默认主键生成规则对带特殊符号的_id识别异常,不同_id的文档被判定为同一缓存键,后续返回的文档会覆盖之前的内容,最终只保留基础版本文档。

解决方法

1. 配置请求授权凭证

首先在Sanity管理后台「设置→API」页面生成一个拥有Viewer权限的只读Token,然后修改Apollo Client配置,给请求添加授权头。如果是Next.js项目,建议将Token存在服务端环境变量中,避免前端泄露:

import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';

const httpLink = createHttpLink({
  uri: 'https://<sanity-id>.api.sanity.io/v1/graphql/test/default',
  credentials: 'same-origin',
});

const authLink = setContext((_, { headers }) => {
  // 替换为你的Sanity Token,Next.js环境可通过process.env读取服务端环境变量
  const sanityToken = '你的Sanity只读Token';
  return {
    headers: {
      ...headers,
      authorization: sanityToken ? `Bearer ${sanityToken}` : '',
    }
  }
});

function createApolloClient() {
  return new ApolloClient({
    ssrMode: typeof window === 'undefined',
    link: authLink.concat(httpLink),
    cache: new InMemoryCache(),
  });
}

如果你的项目允许公开访问所有文档(包括草稿和本地化内容),也可以直接在Sanity后台的数据集权限设置中,将公开访问权限调整为可读取所有文档,不需要额外配置Token。

2. 手动配置缓存规则(可选)

如果添加授权后仍有文档丢失,手动指定缓存主键生成规则,避免冲突:

import { InMemoryCache, defaultDataIdFromObject } from '@apollo/client';

const cache = new InMemoryCache({
  dataIdFromObject: (obj) => {
    if (obj.__typename && obj._id) {
      // 直接用完整的类型名+_id作为缓存键
      return `${obj.__typename}:${obj._id}`;
    }
    return defaultDataIdFromObject(obj);
  }
})

3. 按需过滤文档(可选)

如果你不需要返回草稿内容,可以在GraphQL查询中添加筛选条件,过滤掉drafts.前缀的草稿文档:

query test {
  allPage(filter: { _id: { not: { matches: "drafts.*" } } }) {
    title
    i18n_lang
    _id
  }
}

内容的提问来源于stack exchange,提问作者Kim Vu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 15:06:10