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

如何在Sanity Studio+Next.js中自定义预览模式并获取引用分类数据

解决Sanity Studio预览模式中获取引用分类数据的问题

问题核心是Sanity Studio默认只会返回文档中的引用ID(_ref),不会自动展开引用的关联文档,因此需要手动通过Sanity Client查询分类数据。

步骤1:引入并配置Sanity Client

在structure.ts中创建Studio可用的Sanity客户端,用于查询分类文档:

import { createClient } from '@sanity/client';
import type { SanityDocument } from 'sanity';

// 配置Studio客户端
const client = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
  useCdn: false, // 禁用CDN以获取最新草稿数据
  apiVersion: '2024-01-01', // 使用当前最新API版本
});

步骤2:修正TypeScript接口定义

匹配实际数据结构,categories是引用数组而非单个对象:

interface Doc extends SanityDocument {
  slug: { current: string };
  categories: Array<{ _ref: string; _type: string; _key: string }>;
}

// 分类文档的类型定义
interface Category {
  _id: string;
  title: string;
}

步骤3:重写异步的预览URL生成函数

通过客户端查询引用的分类数据,同时处理异常和 fallback 情况:

async function getPreviewUrl(doc: Doc) {
  const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL || window.location.host;
  
  if (!doc?.slug?.current) {
    return `https://${baseUrl}`;
  }

  // 默认分类 fallback 值
  let categoryTitle = 'uncategorized';
  
  // 若存在分类引用,获取第一个分类的标题
  if (doc.categories?.length > 0) {
    const categoryRef = doc.categories[0]._ref;
    try {
      const category = await client.getDocument<Category>(categoryRef);
      categoryTitle = category.title;
    } catch (err) {
      console.error('获取分类数据失败:', err);
    }
  }

  return `https://${baseUrl}/articles/${categoryTitle}/${doc.slug.current}`;
}

步骤4:更新文档视图配置

Sanity Studio的Iframe视图支持返回Promise的url函数,直接传入异步生成逻辑即可:

export const defaultDocumentNode = (S, { schemaType }) => {
  switch (schemaType) {
    case `article`:
      return S.document().views([
        S.view.form(),
        S.view.component(Iframe).options({
          url: async (doc: Doc) => getPreviewUrl(doc)
        })
      ]);
    default:
      return S.document().views([S.view.form()]);
  }
};

注意事项

  • 确保.env文件中配置了正确的NEXT_PUBLIC_SANITY_PROJECT_ID和NEXT_PUBLIC_SANITY_DATASET环境变量。
  • 如果数据集是私有的,需要在客户端配置中添加token(可在Sanity管理后台生成)。
  • 若文章关联多个分类,可根据需求调整逻辑(比如取第一个、拼接多个分类等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:27:39