Next.js 对接 Sanity 数据库拉取章节图片无法显示问题求助
问题原因
- 你从Sanity查询拿到的
post.Image01是图片资源的结构化对象,不是直接可访问的URL,和你已经正常显示的封面图post.projectImage一样,需要用@sanity/image-url处理后才能赋值给img的src属性,直接把原始对象丢给src自然会加载失败。 - 如果你后续要在
BlockContent渲染的富文本内容里显示图片,还需要给BlockContent组件配置图片渲染的序列化器,否则富文本内的图片也会显示异常。
修复后完整代码
组件部分修改
import imageUrlBuilder from '@sanity/image-url' import { useState, useEffect } from 'react'; import BlockContent from '@sanity/block-content-to-react' // 把图片生成器提出来,避免每次useEffect执行重复实例化 const imgBuilder = imageUrlBuilder({ projectId: 'hidden', dataset: 'production', }); // 封装获取图片URL的工具函数 const urlFor = (source) => imgBuilder.image(source); export const Post = ({ title, image, problem, solution, role, body, body2, body3, body4, body5, photo }) => { const [imageURL, setImageUrl] = useState(''); // 新增photo的url状态 const [photoURL, setPhotoURL] = useState(''); // 富文本图片序列化器,处理富文本内的图片 const serializers = { types: { image: props => <img src={urlFor(props.node)} alt="" className="my-4 max-w-full" /> } } useEffect(() => { setImageUrl(urlFor(image)); // 处理photo的URL if(photo) setPhotoURL(urlFor(photo)); }, [image, photo]); return ( <div> <div className="container mx-auto mt-8 mb-20 px-6"> {imageURL && <img className="my-8" src={imageURL} alt={title} />} <h1 className="text-5xl font-bold my-8">{title}</h1> <div className="flex justify-between space-x-12 mb-8"> <div className="flex flex-col"> <h3 className="text-lg font-semibold">The Problem</h3> <div className="w-auto my-2"> {/* 传入serializers */} <BlockContent blocks={problem} serializers={serializers} /> </div> </div> <div className="flex flex-col"> <h3 className="text-lg font-semibold">The Solution</h3> <div className="w-auto my-2"> <BlockContent blocks={solution} serializers={serializers} /> </div> </div> <div className="flex flex-col"> <h3 className="text-lg font-semibold">Role</h3> <div className="w-auto my-2"> <BlockContent blocks={role} serializers={serializers} /> </div> </div> </div> {/* 替换成处理后的photoURL */} {photoURL && <img src={photoURL} alt="章节配图" />} <div className="w-auto"> <BlockContent blocks={body} serializers={serializers} /> </div> <div className="w-auto"> <BlockContent blocks={body2} serializers={serializers} /> </div> <div className="w-auto"> <BlockContent blocks={body3} serializers={serializers} /> </div> <div className="w-auto"> <BlockContent blocks={body4} serializers={serializers} /> </div> <div className="w-auto"> <BlockContent blocks={body5} serializers={serializers} /> </div> </div> ) };
getServerSideProps部分
不需要修改,保持现有逻辑即可。
注意事项
- 如果图片还是加载失败,可以先在useEffect里打印
photo的内容,确认Sanity返回的是正确的图片对象,包含asset引用字段。 - 记得给所有img标签加上alt属性,符合可访问性规范。
内容的提问来源于stack exchange,提问作者Kristian Abenojar
相关产品推荐
相关产品推荐

