求助:使用PortableText无法显示Sanity块内容中的图片
解决Sanity + Next.js博客中PortableText图片不显示的问题
你的核心问题是PortableText默认不会自动渲染image类型的节点,必须手动配置自定义组件解析Sanity的图片引用,同时确保查询时获取到图片资产的完整信息。以下是具体解决步骤:
1. 安装图片URL生成工具
Sanity提供了专门生成图片URL的包,先安装:
npm install @sanity/image-url
2. 创建自定义图片组件
新建一个Image.js组件(比如放在components目录下),用来处理Sanity图片的引用、裁剪和热点:
import imageUrlBuilder from '@sanity/image-url' // 导入你项目中已配置的sanityClient实例 import { sanityClient } from '../lib/sanity' // 创建URL构建器 const builder = imageUrlBuilder(sanityClient) // 封装生成图片URL的工具函数 function urlFor(source) { return builder.image(source) } export default function Image({ value }) { const { asset, crop, hotspot } = value return ( <img src={urlFor(asset) .crop(crop) .hotspot(hotspot) .fit('max') .auto('format') .url()} alt="" className="w-full h-auto rounded-lg my-4" /> ) }
3. 配置PortableText使用自定义组件
修改你的PostBody组件,给PortableText传入components配置,指定image类型用刚才创建的组件:
import markdownStyles from "./markdown-styles.module.css"; import { PortableText } from "@portabletext/react"; import Image from './Image'; export default function PostBody({ content }) { // 定义PortableText的自定义组件映射 const portableTextComponents = { types: { image: Image, }, }; return ( <div className={`max-w-2xl mx-auto ${markdownStyles.markdown}`}> <PortableText value={content} components={portableTextComponents} /> </div> ); }
注意:你原来的代码里重复写了
className属性,已合并成一个模板字符串避免冲突。
4. 更新GROQ查询,获取图片资产完整数据
你当前获取的content中,图片的asset只是引用(_ref),必须通过GROQ的->操作符展开资产数据,才能拿到图片URL。比如你的查询应该改成:
*[_type == "post" && slug.current == $slug][0] { // 其他字段... content[]{ ..., // 展开image类型的asset引用 _type == "image" => { asset->, crop, hotspot } } }
做完以上步骤,PortableText就能正确渲染图片了。
内容的提问来源于stack exchange,提问作者Cem
相关产品推荐
相关产品推荐

