✨Discover storytelling in the AI age with Pixar's Matthew Luhn at Sanity Connect, May 8th—register now

Adding images to post content using Portable Text and Sanity image URL builder.

9 replies
Last updated: Mar 19, 2023
Hi, How can I add Image into Post content?
Mar 19, 2023, 11:19 AM
Hey
user H
. You can check these docs for that: https://www.sanity.io/docs/portable-text-editor-configuration
Mar 19, 2023, 12:54 PM
Hi
user Z
This is exactly what I'm looking for. Thanks a million!
Mar 19, 2023, 1:14 PM
Hi
user Z
I'm trying to render this in my react code, but it's not working correctly.
/**
 * This component uses Portable Text to render a post body.
 *
 * You can learn more about Portable Text on:
 * <https://www.sanity.io/docs/block-content>
 * <https://github.com/portabletext/react-portabletext>
 * <https://portabletext.org/>
 *
 */
import { PortableText } from '@portabletext/react'
import urlBuilder from '@sanity/image-url'
import {getImageDimensions} from '@sanity/asset-utils'
import styles from './PostBody.module.css'

export default function PostBody({ content }) {
  const myPortableTextComponents = {
    types: {
      image: ({value, isInline}) => <img src={urlBuilder().image(value).width(isInline ? 100 : 800).fit('max').auto('format').url()} />
    },
  }
  return (
    <div className={`mx-auto max-w-2xl ${styles.portableText}`}>
      <PortableText 
        value={content}
        components={myPortableTextComponents}
      />
    </div>
  )
}
Mar 19, 2023, 1:39 PM
With above code, image src is getting url which is missing some value in url.
<https://cdn.sanity.io/images/undefined/undefined/e56314589c88b2176be111f72f9dc5ff7cb4d186-360x360.jpg?w=800&fit=max&auto=format>
Mar 19, 2023, 1:40 PM
As I check in sanity dashboard, correct url is having
/{SANITY_API_PROJECT_ID}/production
, but my components is getting
/undefined/undefined/
Mar 19, 2023, 1:41 PM
What should I add/update to fix this?
Mar 19, 2023, 1:42 PM
I believe the issue is your urlBuilder needs those details. Check @sanity/image-url for more information please
Mar 19, 2023, 1:43 PM
Yeah, thanks. I've updated my code as described in @anity/image-url, and it works great now!
/**
 * This component uses Portable Text to render a post body.
 *
 * You can learn more about Portable Text on:
 * <https://www.sanity.io/docs/block-content>
 * <https://github.com/portabletext/react-portabletext>
 * <https://portabletext.org/>
 *
 */
import { PortableText } from '@portabletext/react'
import { apiVersion, dataset, projectId } from 'lib/sanity.api'
import urlBuilder from '@sanity/image-url'
import { createClient } from 'next-sanity'
import {getImageDimensions} from '@sanity/asset-utils'
import styles from './PostBody.module.css'

export default function PostBody({ content }) {
  const client = createClient({ projectId, dataset, apiVersion, useCdn: false })
  const SampleImageComponent = ({value, isInline}) => {
    const {width, height} = getImageDimensions(value)
    return (
      <img
        src={urlBuilder(client)
          .image(value)
          .width(isInline ? 100 : 800)
          .fit('max')
          .auto('format')
          .url()}
        alt={value.alt || ' '}
        loading="lazy"
        style={{
          // Display alongside text if image appears inside a block text span
          display: isInline ? 'inline-block' : 'block',
  
          // Avoid jumping around with aspect-ratio CSS property
          aspectRatio: width / height,
        }}
      />
    )
  }
  const components = {
    types: {
      image: SampleImageComponent,
      // Any other custom types you have in your content
      // Examples: mapLocation, contactForm, code, featuredProjects, latestNews, etc.
    },
  }
  return (
    <div className={`mx-auto max-w-2xl ${styles.portableText}`}>
      <PortableText 
        value={content}
        components={components}
      />
    </div>
  )
}
Mar 19, 2023, 1:53 PM
I was missing to pass sanityClient param to
urlBuilder
function.
Mar 19, 2023, 1:55 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?