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

基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:45:55