Next.js Discord

Discord Forum

Next Image how do I conditionally render with potentially empty source?

Answered
Whiteleg shrimp posted this in #help-forum
Open in Discord
Whiteleg shrimpOP
I'm trying to make the Image component show with the proper size, but not render the image itself until its fully loaded. Here's my code at the moment:
'use client'
import NextImage from "next/image"

import { APIResponse } from "@/app/page"
import { useState } from "react";

export default function Image({ image }: Readonly<{ image: APIResponse }>) {
  const [loading, setLoading] = useState(true);

  return (
    <div className={`bg-zinc-800 rounded-xl w-full h-${image.height} mb-8 overflow-hidden ${loading ? "animate-pulse" : ""}`}>
      <a href={image.url}>
        <NextImage
          placeholder="empty"
          src={image.download_url}
          width={image.width}
          height={image.height}
          onLoad={() => setLoading(false)}
          alt="" />
      </a>
    </div>
  )
}

Despite placeholder being set to empty, the image shows as slowly loading when I test with slow mobile connection throttling. It's almost what I want but its really annoying to look at. I would like to just set source to an empty string, but when I do that it tells me that it should either be null or to not render NextImage altogether. When I set it to null it gives me some bullshit error about the type not matching despite it suggesting to use null :/

Here's the error if it matters but its just mismatched type:
Type 'string | null' is not assignable to type 'string | StaticImport'.
  Type 'null' is not assignable to type 'string | StaticImport'.ts(2322)


Here's a video of what I mean: https://youtu.be/VLFbl8ZllxE
Answered by Whiteleg shrimp
Found a simple solution that took way too long to think of. Conditionally give it a style of opacity 0% if its loading. The Image looks like this:
<NextImage
          placeholder="empty"
          src={image.download_url}
          width={image.width}
          height={image.height}
          className={loading ? "opacity-0" : ""}
          onLoad={() => setLoading(false)}
          alt="" />
View full answer

2 Replies

Whiteleg shrimpOP
did not realize the video quality was so bad, but it should be good enough to see what the issue is.
Whiteleg shrimpOP
Found a simple solution that took way too long to think of. Conditionally give it a style of opacity 0% if its loading. The Image looks like this:
<NextImage
          placeholder="empty"
          src={image.download_url}
          width={image.width}
          height={image.height}
          className={loading ? "opacity-0" : ""}
          onLoad={() => setLoading(false)}
          alt="" />
Answer