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

Sanity Studio多语言场景下如何实现当前Locale无文档时的回退查询

问题根因

当前的GROQ查询使用了无优先级的OR逻辑,只要文档满足「匹配目标语言」或「匹配默认语言」任意一个条件就会被返回,没有对同一内容的多语言版本做去重和优先级判断。当某份内容同时存在目标语言、默认语言两个版本时,两个版本都会被查出,前端如果没有做二次筛选,就会出现重复条目、错误渲染默认语言内容的问题。

正确的回退实现

基于sanity-plugin-intl-input的文档元数据特性:同一内容的所有语言版本,都会通过固定的关联ID做绑定。可以通过分组排序实现「优先匹配目标语言,目标语言无对应内容时自动回退到默认语言」的逻辑,从查询层面就避免返回重复的多语言条目,具体实现思路:

  • 先过滤掉非目标语言、非默认语言的无效文档,减少查询计算量
  • 按照同一内容的i18n关联ID对文档做分组
  • 组内按优先级排序:目标语言条目的优先级高于默认语言条目,每组只保留优先级最高的那一条

适配常用的老版本插件(元数据为顶级__i18n_lang字段)的查询语句如下:

*[_type == "cardPage" && !(_id in path('drafts.**'))]
  [__i18n_lang in [$locale, $defaultLocale]]
  {
    "validDoc": @[]{
      // 计算优先级:目标语言排序更靠前,优先级更高
      "priority": select(
        __i18n_lang == $locale => 0,
        __i18n_lang == $defaultLocale => 1
      ),
      ...this
    } | order(priority asc)[0]
  }.validDoc

如果是单详情页的查询,只需在最外层的过滤条件里补充对应路由参数(比如匹配slug值)即可,后续的分组优先级逻辑保持不变。

注意事项
  • 如果使用的是新版本的sanity-plugin-intl-input,i18n元数据会嵌套在__i18n对象下,只需把查询里的__i18n_lang替换为__i18n.lang,对应调整关联分组的字段名即可
  • 单文档查询场景下,不要直接使用目标语言 || 默认语言的无优先级条件,这类逻辑只会返回所有满足条件的文档,无法实现回退需要的优先级判断
  • 前端拿到查询结果后不需要额外做语言过滤,返回的每一条文档都已经是对应内容下优先级最高的语言版本

内容的提问来源于stack exchange,提问作者Mahabubur Rahman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 09:24:04