Image Uploaded to WYSIWYG - Link Provided on the Sanity CDN Doesn't Work
Glad to hear your blog is working nicely! This is a common issue when working with images in Portable Text. The problem is that Sanity stores image references as asset objects, not ready-to-use URLs. You need to transform these references into proper CDN URLs using @sanity/image-url.
Here's what's happening: when you add an image in the Portable Text editor (WYSIWYG), Sanity stores it as a reference object with an _type of image and an asset reference. But to actually display it, you need to process that reference through Sanity's image URL builder to get a working cdn.sanity.io URL.
The solution is to create a custom serializer for image blocks in your Portable Text renderer using @portabletext/react:
import { PortableText } from '@portabletext/react'
import imageUrlBuilder from '@sanity/image-url'
import { client } from './sanityClient' // your Sanity client
// Set up the image URL builder
const builder = imageUrlBuilder(client)
function urlFor(source) {
return builder.image(source)
}
// Custom serializers for Portable Text
const components = {
types: {
image: ({value}) => {
if (!value?.asset?._ref) {
return null
}
return (
<img
src={urlFor(value).width(800).url()}
alt={value.alt || ' '}
loading="lazy"
/>
)
}
}
}
// Use it in your component
function BlogPost({ content }) {
return <PortableText value={content} components={components} />
}Key steps:
- Install
@sanity/image-urlif you haven't:npm install @sanity/image-url - Create an image URL builder instance with your Sanity client
- Add a custom serializer for the
imagetype in your Portable Text components - Use the builder to transform the asset reference into a working cdn.sanity.io URL
You can also add image transformations like .width(), .height(), .fit(), .quality(), or even .auto('format') for automatic WebP/AVIF format selection to optimize the images for your needs.
If your images are structured differently (like custom image blocks), you might need to adjust the value.asset._ref path to match your schema. The important part is passing the image reference through the URL builder before rendering it.
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.