Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility with Gatsby 3 & workaround (☂️ Umbrella Issue) #141

Open
YannickMol opened this issue Jan 27, 2021 · 19 comments
Open

Compatibility with Gatsby 3 & workaround (☂️ Umbrella Issue) #141

YannickMol opened this issue Jan 27, 2021 · 19 comments
Assignees
Labels
already in progress This was already worked on not stale This issue has gone quiet but will be kept open

Comments

@YannickMol
Copy link

YannickMol commented Jan 27, 2021

Hi Team,

As the new version of gatsby-image is coming up in the form of the gatsby-plugin-image plugin, I was wondering whether this will be reflected in a new version of the gatsby-background-image plugin. When using the new API and gatsbyImageData in a BackgroundImage component, it gives the following error: Warning: Failed prop type: Invalid prop "fluid" supplied to "BackgroundImage"..

Thanks,
Yannick

@timhagn
Copy link
Owner

timhagn commented Feb 2, 2021

Hi Yannick,

wished I were a team, but I'm flying solo on gbi ; ).
Already looked into the new plugin, see #132, but didn't look into its Types.
Will try to rectify this week - or feel free to open a PR : ).

Best,

Tim.

@timhagn
Copy link
Owner

timhagn commented Feb 7, 2021

Hi @YannickMol,

just looked into it & have to say: Uffz. Quite another paradigm of handling images oO.
Trying to implement a converter function for the new gatsbyImageData Type, but couldn't replicate your error...
Would you be able to give me some sources or (even better) a reproduction repo?

Scratch that, the aspectRatio was missing, as the gatsbyImageData Type directly gives width & height instead of it.

Best,

Tim.

@timhagn
Copy link
Owner

timhagn commented Feb 7, 2021

Hi @YannickMol, again.

As written above, I just worked on a converter function. It isn't completely finished & I'm gonna try adding it to gbi in the upcoming week, but should you want to try it, have a look below : ).

import React from 'react'
import { graphql, useStaticQuery } from 'gatsby'
import { GatsbyImage, getImage } from "gatsby-plugin-image"
import BackgroundImage from "gatsby-background-image"

// ------------------ COPY FROM HERE -------------------------------------------
// Helper functions.
const getBgImageType = imageData => imageData.layout === 'fixed' ? 'fixed' : 'fluid'
const getAspectRatio = imageData => imageData.width / imageData.height
const getPlaceholder = imageData => {
  if (imageData.placeholder) {
    return imageData.placeholder.fallback.includes(`base64`) ?
      { base64: imageData.placeholder.fallback }
      : { tracedSvg: imageData.placeholder.fallback }
  }
  return {}
}

/**
 * Tries to Backport the new `gatsbyImageData` type to the classic `fluid` / `fixed` form.
 *
 * @param imageData   {object}    The image data to convert.
 * @returns {{}}
 */
const convertToBgImage = imageData => {
  if (imageData && imageData.layout) {
    const returnBgObject = {}
    const bgType = getBgImageType(imageData)
    const aspectRatio = getAspectRatio(imageData)
    const placeholder = getPlaceholder(imageData)
    returnBgObject[bgType] = {
      ...imageData.images.fallback,
      ...placeholder,
      aspectRatio,
    }
    return returnBgObject
  }
  return {}
}
// ------------------ TO HERE --------------------------------------------------

const GpiTest = () => {
  const {placeholderImage, oldImage} = useStaticQuery(
    graphql`
      query {
        placeholderImage: file(relativePath: { eq: "gatsby-astronaut.png" }) {
          childImageSharp {
            gatsbyImageData(
              width: 200
              placeholder: BLURRED
              formats: [AUTO, WEBP, AVIF]
            )
          }
        }
      }
    `
  )
  const image = getImage(placeholderImage)

  // Use like this:
  const bgImage = convertToBgImage(image)

  return (
    <BackgroundImage
      Tag="section"
      // Spread bgImage into BackgroundImage:
      {...bgImage}
      preserveStackingContext
    >
      <div style={{minHeight: 1000, minWidth: 1000}}>
        <GatsbyImage image={image} alt={"testimage"}/>
      </div>
    </BackgroundImage>
  )
}
export default GpiTest

WebP (& AVIF) handling is currently missing (& for the latter I have to adapt gbi), but at least at my place it worked like the above. Have phun : )!

Best,

Tim.

P.S.: With this function you could use the new type with the "old" GatsbyImage as well, should you want to ; ).

@github-actions
Copy link

Hi there!
As @timhagn momentarily is the main contributor to this package, this issue
has been automatically marked as stale because it has not had
any recent activity.
It will be closed if no further activity occurs, though we're open to
suggestions on how to get more maintainers!
Thank you for your contributions : )!

@github-actions github-actions bot added the stale? This issue has gone awfully quiet... label Feb 24, 2021
@timhagn timhagn added not stale This issue has gone quiet but will be kept open and removed stale? This issue has gone awfully quiet... labels Feb 24, 2021
@rburgst
Copy link

rburgst commented Mar 8, 2021

I have created a simple wrapper that can be used as a 1:1 replacement for <BackgroundImage> until its fully compatible. Note that I only use fluid images. So you might need to tweak a little bit.

// Helper functions.
import BackgroundImage, { IBackgroundImageProps, IFixedObject, IFluidObject } from 'gatsby-background-image'
import { getImage } from 'gatsby-plugin-image'
import { IGatsbyImageData } from 'gatsby-plugin-image/dist/src/components/gatsby-image.browser'
import React, { CSSProperties } from 'react'
import { FunctionComponent } from 'react'

const getBgImageType = (imageData: IGatsbyImageData) => (imageData.layout === 'fixed' ? 'fixed' : 'fluid')
const getAspectRatio = (imageData: IGatsbyImageData) => imageData.width / imageData.height
const getPlaceholder = (imageData: IGatsbyImageData) => {
  if (imageData.placeholder) {
    return imageData.placeholder!.fallback?.includes(`base64`)
      ? { base64: imageData.placeholder!.fallback }
      : { tracedSVG: imageData.placeholder!.fallback }
  }
  return {}
}

/**
 * Tries to Backport the new `gatsbyImageData` type to the classic `fluid` / `fixed` form.
 *
 * @param imageData   {object}    The image data to convert.
 * @returns {{}}
 */
export function convertToBgImage(imageData: IGatsbyImageData): Partial<IBackgroundImageProps> {
  if (imageData && imageData.layout) {
    const returnBgObject: Partial<IBackgroundImageProps> = {}
    const bgType = getBgImageType(imageData)
    const aspectRatio = getAspectRatio(imageData)
    const placeholder = getPlaceholder(imageData)
    // @ts-ignore
    returnBgObject[bgType] = {
      ...imageData.images.fallback,
      ...placeholder,
      aspectRatio,
    }
    return returnBgObject
  }
  return {}
}

export interface IBgImageProps {
  fluid?: IGatsbyImageData
  className?: string
  onClick?: (e: Event) => void
  tabIndex?: number
  fadeIn?: boolean
  id?: string
  style?: CSSProperties
  role?: string
  preserveStackingContext?: boolean
}

/**
 * This is a temporary stopgap solution until `<BackgroundImage>` natively supports `gatsby-plugin-image`,
 * see [https://github.com/timhagn/gatsby-background-image/issues/141](https://github.com/timhagn/gatsby-background-image/issues/141).
 * @param {React.PropsWithChildren<IBgImageProps>} props
 * @return {JSX.Element}
 * @constructor
 */
export const BgImage: FunctionComponent<IBgImageProps> = (props) => {
  const { fluid, children, ...args } = props
  if (fluid) {
    const image = getImage(fluid)
    const bgImage = image && convertToBgImage(image)
    return (
      <BackgroundImage {...bgImage} {...args}>
        {children}
      </BackgroundImage>
    )
  } else {
    return <div>{children}</div>
  }
}

Depending on which other features you need, you might need to add them to IBgImageProps

@joernroeder
Copy link

@timhagn @rburgst The getPlaceholder helper needs to return the traced svg as { tracedSVG: 'svg...' } not tracedSvg.

@mwskwong
Copy link

Currently, this workaround is very basic. I'm planning to extend this to support webp and art direction as well.

@timhagn @rburgst, I'm trying to also support avif as well. The original fluid object has srcWebp and srcSetWebp fields, I imagine if I specify srcAvif and srcSetAvif, they will be simply ignored?

@timhagn timhagn changed the title Error with new gatsby-plugin-image plugin Compatibility with Gatsby 3 & workaround (☂️ Umbrella Issue) Mar 13, 2021
@timhagn timhagn self-assigned this Mar 13, 2021
@timhagn timhagn pinned this issue Mar 13, 2021
@timhagn timhagn added the already in progress This was already worked on label Mar 13, 2021
@timhagn
Copy link
Owner

timhagn commented Mar 13, 2021

Hi @ALL!

Wow, thanks for the effort to all of you! Great enhancement of my meager backport @rburgst : )!
And you're right @matthewkwong2, right now srcAvif and srcSetAvif would simply be ignored right now,
but I'm just working on it : )!

Best,

Tim.

@timhagn
Copy link
Owner

timhagn commented Mar 13, 2021

Hi again @ALL,

if you head over to the gbimage-bridge branch & package, you may see the proceedings of the new adapter and may of course add your knowledge and code : )!

Best,

Tim.

@timhagn
Copy link
Owner

timhagn commented Mar 13, 2021

Hi again @ALL!

Uffz, heavy lifting. It's alread working with WebP (see g3bitest ; ).
Nearly there, just a few more steps:

  • add type & sizes to source sets
  • add iterator over all srcSet${Type}s

Hope to finish it tomorrow, but any help welcome in the meantime (see here) : )!

Best,

Tim.

@timhagn
Copy link
Owner

timhagn commented Mar 15, 2021

And once more with feeling: Hi @ALL!

Just published the first version of gbimage-bridge & new versions of gbi(-es5).
In combination it now has:

  • support for the new gatsby-plugin-image query syntax (in GbImage & solo through convertToBgImage())
  • AVIF support
  • conversion for art-directed / stacked images

Have a look at gbimage-bridge, grab [email protected] & give it a spin : )!

Best,

Tim.

P.S.: The resulting image from the conversion could even be used with classic gatsby-image for whomever can't update right now, so thanks for giving me a push to create this ; )!

@mwskwong
Copy link

@timhagn It's a bit weird you decided to publish it as a separated package. I thought there will be a new major release of the original one.

@timhagn
Copy link
Owner

timhagn commented Mar 16, 2021

Hi @matthewkwong2,

it was way faster to write the bridge & gain more experience with the new format than going through all the code and every important moving part to rip our fluid / fixed & replace it with IGatsbyImageData ^^.

Next step (apart from trying to fix more issues % ) is a rewrite, as the current code has become quite a behemoth through "organic growth" that everything should be revisited. Especially looking at the LCP-Score & suchlike ; ).

Best,

Tim.

@JStumpp
Copy link

JStumpp commented Mar 16, 2021

Hi @timhagn,

thanks a lot, it works, but there is one major issue, the images all seem to load twice. Even in your demo repository you can see it in the network: https://github.com/timhagn/g3bitest

image

Any ideas?

@mwskwong
Copy link

Hi @timhagn,

thanks a lot, it works, but there is one major issue, the images all seem to load twice. Even in your demo repository you can see it in the network: https://github.com/timhagn/g3bitest

image

Any ideas?

I notice the same thing. While this issue also happens on gatsby-plugin-image as well.

@timhagn
Copy link
Owner

timhagn commented Mar 16, 2021

hmmz Would have to invest a little more, but I guess this has to do with #125.
The bug I opened in the Gatsby repo for it just got closed -.-
And when you say:

While this issue also happens on gatsby-plugin-image as well.

we might perhaps give them a shout, or what do you think?

@mwskwong
Copy link

mwskwong commented Mar 16, 2021

Already done it in gatsbyjs/gatsby#30272

@pkuczynski
Copy link

@timhagn I know you are the only person working on this, but do you have any ETA when this will be available without the gbimage-bridge? No pressure of course...

@mwskwong
Copy link

Already done it in gatsbyjs/gatsby#30272

This issue seems to be fixed with the latest release of gatsby-plugin-image and gatsby-transformer-sharp. Guess it is not our fault after all. It would be great if someone else can verify that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
already in progress This was already worked on not stale This issue has gone quiet but will be kept open
Projects
None yet
Development

No branches or pull requests

7 participants