reactjsnext.jssanitynextjs-imagegroq

New nextjs 13 next/image component not loading with sanity.io image


I'm trying to get a simple next/image component displaying properly but the images just won't load. I'm using nextjs 13 which was just released so this is a new version of the component.

I'm using sanity.io on the back and my images are stored there. I'm unclear as to whether this issue is caused by the new next/image component or if something is going wrong with my code. The src and alt props are getting passed properly and the source seems to be registering properly (image below) but the the image isn't displaying.

/app/Figure.tsx:

"use client";
import Image from "next/image";

interface Props {
  src: string;
  alt: string;
  width: number;
  height: number;
}

export default function Figure(props: Props) {
  return (
    <figure>
      <style jsx>{`
        figure {
          position: relative;
          width: 100%;
          margin: 0;
          padding-top: ${((props.height / props.width) * 100).toFixed(2)}%;
        }
      `}</style>
      <Image src={props.src} alt={props.alt} fill />
    </figure>
  );
}

next.config.js:

  images: {
    domains: ["cdn.sanity.io", "images.pexels.com"],
  },

Result enter image description here enter image description here


Solution

  • If you're fetching an image directly, you'll need to translate the fetched data response to a blob and then create an object URL (URL.createObjectURL) for the Image tag to use as the source.

    I've made a Stackblitz demo as well.

    import Image from 'next/image';
    import React from 'react';
    import useSWR from 'swr';
    
    const fetcher = (url) => fetch(url).then((res) => res.blob());
    
    export default function App() {
      const url = 'https://source.unsplash.com/random';
      const { data, error } = useSWR(url, fetcher);
    
      if (error) return 'An error has occurred.';
      if (!data) return 'Loading...';
    
      const dataUrl = URL.createObjectURL(data);
    
      return (
        <figure>
          <style jsx>{`
          figure {
            position: relative;
            width: 100%;
            margin: 0;
            padding-top: ${((200 / 200) * 100).toFixed(2)}%;
          }
        `}</style>
          <Image src={dataUrl} alt={'test'} fill />
        </figure>
      );
    }