question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Error fallback image with loadEagerly?

See original GitHub issue

I need an image that should be rendered asap (I’m using SSR with next.js), and currently I’m using the loadEagerly prop in this image… However, I found interesting that if for some reason this image doesn’t exist, display the fallback image… Looks that with loadEagerly is only rendering the actual.

There is some another option to do it?

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
fpapadocommented, Apr 18, 2019

I think the workaround that you mention with onError is the best way to handle loadEagerly + error handling at the moment.

The second scenario with loadEagerly={!process.browser} will have quirks, because the image will be re-rendered when the client sripts rehydrate. This is why you get the “blinking” behaviour even if there is no error - it’s the image entering the “Loading” state again.

The reason the workaround only works sometimes, as far as I can tell, is that the event could fire before the client scripts have downloaded/parsed/executed. I don’t think it’s Next.js specific, but rather how hydration and events work. I could be wrong though!

A potential solution

This discussion does give me an idea:

  • If the image has loadEagerly, then we move to a new state, Refreshing
  • In that Referesing state, we would keep rendering the actual, and also kick off an observed image load
  • When the new image comes in, or fails, we move to Loaded or Error states, as before

In theory, this means:

  • If the image has been fetched by the browser already, then it’s in cache, and there should be no blinking (no Loading state) when we “swap”
  • If the image was broken, and the new load is broken, then error is used

I have some free time over the next few days, and was looking into tackling some leftover issues here. I’ll let you know if I manage to get a beta version out. No guarantees that it’ll work, but we can try it and get some feedback 😃

0reactions
aralrocacommented, Apr 18, 2019

Better detailed:

hook:

import { useRef, useCallback, useEffect } from 'react'
import noop from 'lodash/noop'

/**
 * Using loadEagerly, with SSR the image is displayed ASAP,
 * in the first render.
 *
 * With loadEagerly activated, the "error" prop of LazyImage
 * component is not rendering. So, in order to workaround the fallback image,
 * I need to do two things:
 *
 * * Catch the event onError and change the src with the fallback image
 * * Check in the "didMount" (useEffect) that if is completed and doesn't
 *   have height, this means that there is an error, and how is completed
 *   before the hydration, the onError event was not fired by React. So in
 *   this case also the src shoud be changed to the fallback image.
 */
export default function useLoadEagerlyFallbackImage(fallbackSrc) {
  const ref = useRef(null)

  /**
   * Error happened / catched after hydration
   */
  const onError = useCallback(
    e => { e.target.src = fallbackSrc }, [fallbackSrc],
  )

  /**
   * Error happened before hydration, but catched after hydration
   */
  useEffect(() => {
    if (ref && ref.current) {
      const { complete, naturalHeight } = ref.current
      const errorLoadingImgBeforeHydration = complete && naturalHeight === 0

      if (errorLoadingImgBeforeHydration) {
        ref.current.src = fallbackSrc
      }
    }
  }, [fallbackSrc])

  return { ref, onError }
}

Usage:

const loadEagerlyProps = useLoadEagerlyFallbackImage(fallbackSrc)

return (
  <LazyImage
    loadEagerly
    src={src}
    alt=""
    actual={({ imageProps }) => (
     <img {...imageProps} {...loadEagerlyProps} />
     )}
  />
)
Read more comments on GitHub >

github_iconTop Results From Across the Web

HTML fallback images on error - Daily Dev Tips
So I decided to look into fallback images. And it's surprisingly easy. What we want to achieve: Load the image; If it doesn't...
Read more >
Configure Fallback Images in React and Next.js
Therefore, I created a piece of state so I could rerender the component in case of an error: import fallback from "../public/fallback-image.png" ...
Read more >
react-lazy-images - npm Package Health Analysis - Snyk
React utilities for lazy image loading For more information about how to use this package see README. Latest version published 4 years ago....
Read more >
Embedded content - 4.8.1 - The picture element - HTML Spec
< script > function fallback ( video ) { // replace <video> with its contents ... The images load eagerly and delay the...
Read more >
Native image lazy-loading for the web - Hacker News
The problem with the tech bubble these days is that people within it ... I would prefer to choose for myself whether images...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found