sanity
sanity copied to clipboard
Querying images from the Content Lake returns the wrong type
Describe the bug
I am trying to implement a SanityImage
component in my Nextjs 14 app. Here's what I've come up with:
import { getImageDimensions, ResolvedSanityImage } from '@sanity/asset-utils';
import { getURL } from '@/lib/sanity/helpers';
import Image from 'next/image';
import { HTMLAttributes } from 'react';
interface Props extends HTMLAttributes<HTMLImageElement> {
value: ResolvedSanityImage;
}
const SanityImage = ({ value, ...props }: Props) => {
const { width, height } = getImageDimensions(value);
if (value.asset) {
return (
<Image
src={getURL(value).url()}
alt=''
loading='lazy'
width={width}
height={height}
placeholder='blur'
blurDataURL={getURL(value).height(24).width(24).blur(10).url()}
{...props}
/>
);
}
};
export default SanityImage;
The getURL
function looks like this:
export const getURL = (src: ResolvedSanityImage) => {
const builder = createImageUrlBuilder(client);
return builder.image(src);
};
However, when trying to use it to render an image queried with GROQ I get this type error:
Type '{ asset?: { _ref: string; _type: "reference"; _weak?: boolean | undefined; [internalGroqTypeReferenceTo]?: "sanity.imageAsset" | undefined; } | undefined; hotspot?: SanityImageHotspot | undefined; crop?: SanityImageCrop | undefined; _type: "image"; } | undefined' is not assignable to type 'ResolvedSanityImage'.
Type 'undefined' is not assignable to type 'ResolvedSanityImage'.ts(2322)
Am I using the wrong types? Do I need to modify the image component? How do I make sure that the image is only rendered when value.asset
is defined (as that is the problem I'm suspecting this all stems from)? Especially in scenarios such as this:
function Component1({ images }: { images: ResolvedSanityImage[] }) {
return (
<div className='flex'>
{images!.map((image) => (
<SanityImage value={image} />
))}
</div>
);
}
export default async function ProjectsPage({}: Props) {
const projects = await sanityFetch<PROJECTS_QUERYResult>({
query: PROJECTS_QUERY,
});
return (
<div>
{projects.map((project) => (
<Component1 images={project.images} />
))}
</div>
);
}
To Reproduce
- Create a new Next app and connect Sanity
- Query some content with an image in the schema
- Copy and paste the code above
Expected behavior
No type errors.
Which versions of Sanity are you using?
@sanity/cli (global) 3.52.4 (latest: 3.54.0) @sanity/asset-utils 1.3.0 (up to date) @sanity/image-url 1.0.2 (up to date) @sanity/vision 3.52.4 (latest: 3.54.0) sanity 3.52.4 (latest: 3.54.0)
What operating system are you using?
Windows 11
Which versions of Node.js / npm are you running?
pnpm 9.7.0, node v20.12.2