How to override the default preview configuration for an image block in Portable Text in Sanity.io
6 replies
Last updated: Sep 28, 2022
J
Hi all. I’m trying to write a
Sanity correctly resolves the reference to the asset and the preview includes a thumbnail of the image, but it appears as “Untitled”. If I also want to retrieve other fields on the asset, e.g. the
It looks like using the dot notation somehow prevents the built-in image handling code from following the reference. I can do this instead, specifically picking out the image url, but it results in the full-size image being loaded which isn’t ideal:
I would need to write more code to request a thumbnailed version of the image using the asset API. Is there a way to avoid this so I can just use a simple
previewconfiguration for an
imageblock within Portable Text. By default, the image is shown in thumbnail form with its filename as the preview title. In trying to override that I started with the following:
preview: { select: { media: 'asset', }, },
altText, using the dot-notation to follow the reference, it breaks the image handling. This doesn’t work:
preview: { select: { media: 'asset', title: 'asset.altText', }, },
preview: { select: { image: 'asset', alt: 'asset.altText', imageUrl: 'asset.url', }, prepare (selection) { const { image, alt, imageUrl } = selection; return { title: alt, media: ( <img src={imageUrl} alt={alt} /> ), }; }, },
selectwithout a complicated
prepare, but still be able to pick out asset fields as well as using the built-in handling of the asset itself? Thanks!
Sep 28, 2022, 11:16 AM
J
Re that extra code, this is what I’ve ended up with, pulling in the necessary extra fields to build the image URL – it does work, but it would be really good to avoid this boilerplate if the built-in image handling could be made to behave when extra fields on the asset are queried.
import React from 'react'; import SanityImageUrlBuilder from '@sanity/image-url'; const imageUrlBuilder = SanityImageUrlBuilder({ projectId: process.env.SANITY_STUDIO_API_PROJECT_ID, dataset: process.env.SANITY_STUDIO_API_DATASET, }); export default { // ... preview: { select: { asset: 'asset', _id: 'asset._id', altText: 'asset.altText', assetId: 'asset.assetId', extension: 'asset.extension', metadata: 'asset.metadata', originalFilename: 'asset.originalFilename', path: 'asset.path', url: 'asset.url', }, prepare ({ asset }) { const url = imageUrlBuilder.image(asset).width(33).height(33).fit('crop').url(); return { title: asset.altText || asset.originalFilename, media: ( <img src={url} alt={asset.altText} /> ), }; }, }, };
Sep 28, 2022, 11:47 AM
J
OK, I solved this! When using dot notation the type of the reference gets changed to
sanity.imageAsset. It’s necessary to set it back to
referenceto allow the default preview component to understand the image:
preview: { select: { asset: 'asset', altText: 'asset.altText', originalFilename: 'asset.originalFilename', }, prepare ({ asset, altText, originalFilename }) { return { title: altText || originalFilename, media: { ...asset, _type: 'reference', }, }; }, },
Sep 28, 2022, 12:13 PM
J
I’m not sure how commonplace this use-case is but it might be worth adding a note to this section of documentation to cover it off?
Sep 28, 2022, 12:16 PM
J
Thank you!
Sep 28, 2022, 5:00 PM
J
Sorry, it was a bit of a journey 😛
Sep 28, 2022, 5:00 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.