基于Sanity后端与Next.js前端,如何在PortableText中显示富文本块内容图片?
解决Sanity PortableText在Next.js中不显示图片的问题
默认的PortableText组件只会处理基础文本块,不会自动渲染Sanity富文本中的图片——因为图片是独立的自定义块类型,需要你配置自定义渲染器来处理。以下是具体实现步骤:
1. 安装依赖(如果未安装)
确保你已安装next-sanity(用于图片URL生成和Next.js兼容):
npm install next-sanity # 或 yarn add next-sanity
2. 配置Sanity图片URL生成工具
在你的Sanity工具目录(比如sanity/lib/image.js)中创建图片URL生成器:
import createImageUrlBuilder from '@sanity/image-url' import { dataset, projectId } from '@/sanity/env' const imageBuilder = createImageUrlBuilder({ projectId: projectId || '', dataset: dataset || '', }) export const urlForImage = (source) => { return imageBuilder?.image(source).auto('format').fit('max') }
3. 创建图片渲染组件
新建一个组件(比如components/PortableTextImage.jsx)来处理Sanity图片块的渲染:
import { urlForImage } from '@/sanity/lib/image' import Image from 'next/image' export const PortableTextImage = ({ value }) => { // 生成适配的图片URL const imageUrl = urlForImage(value.asset).width(800).url() return ( <div className="my-8"> <Image src={imageUrl} alt={value.alt || '博客文章图片'} width={800} height={600} className="rounded-lg w-full object-cover" /> {/* 渲染图片说明文字(如果有) */} {value.caption && <p className="text-sm text-gray-500 mt-2">{value.caption}</p>} </div> ) }
4. 给PortableText组件传入自定义渲染器
在你的博客页面组件中,修改PortableText的调用,通过components属性指定图片类型的渲染组件:
import PortableText from '@portabletext/react' import { PortableTextImage } from '@/components/PortableTextImage' export default function BlogPost({ blog }) { return ( <article> <h1>{blog.title}</h1> <PortableText value={blog.body} components={{ types: { // 将Sanity中的image类型块映射到自定义组件 image: PortableTextImage, }, }} /> </article> ) }
5. 配置Next.js图片域名白名单
在next.config.js中添加Sanity图片CDN的域名,避免Next.js Image组件的跨域限制:
/** @type {import('next').NextConfig} */ const nextConfig = { images: { remotePatterns: [ { protocol: 'https', hostname: 'cdn.sanity.io', pathname: `/images/${process.env.NEXT_PUBLIC_SANITY_PROJECT_ID}/${process.env.NEXT_PUBLIC_SANITY_DATASET}/**`, }, ], }, } module.exports = nextConfig
6. 验证Sanity Schema配置
确保你的Sanity博客文档Schema中,body字段的of数组包含图片类型定义(带必要的辅助字段):
export default { name: 'blog', type: 'document', fields: [ // 其他字段(标题、日期等)... { name: 'body', type: 'array', of: [ { type: 'block' }, // 基础文本块 { type: 'image', options: { hotspot: true }, // 支持图片热点裁剪 fields: [ { name: 'alt', type: 'string', title: '替代文本', validation: Rule => Rule.required() // 强制添加替代文本,优化SEO }, { name: 'caption', type: 'string', title: '图片说明' } ] } ] } ] }
完成以上步骤后,重新启动Next.js应用,富文本中的图片就会正常渲染了。
内容的提问来源于stack exchange,提问作者Mohid Naeem
相关产品推荐
相关产品推荐

