-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
feat(gatsby-plugin-image): Add image plugin helpers #28110
Conversation
92cb349
to
ecb1fe7
Compare
ecb1fe7
to
2972f07
Compare
5022170
to
f167daf
Compare
@@ -0,0 +1 @@ | |||
export * from "./dist/resolver-utils" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved the graphql helper into a separate subpackage. Having them in the main gatsby-plugin-image was causing build problems, as it was trying to import graphql it when building SSR pages, causing build failures. Moving it into "gatsby-plugin-image/graphql"
fixes that. I'm guessing this is the reason gatsby re-exports graphql from a subpackage too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks reasonable to me 👍🏻
The new Gatsby image plugin uses a new data format, which is not compatible with existing resolvers. Plugins that use
childImageSharp
can use the new resolvergatsbyImageData
, with a codemod for easy migration. However this will not work for plugins that provide their own gatsby image-compatible resolvers. These plugins will need to add a new resolver if their users are to be able to make use of the new component, with the improved performance and Lighthouse scores that go along with it.Plugins that implemented a gatsby image-compatible resolver have previously had to reverse-engineer the sharp transformer, as there was no approved way to easily handle this.
Gatsby image plugin helpers
We are aware that it is asking a lot of plugin authors to add a whole new resolver. With that in mind, we are proposing a new set of helper functions designed to simplify the job, meaning that you only need to provide the logic to generate image URLs, while we handle the boilerplate of creating the resolver and data. The returned data can be passed directly to a
GatsbyImage
component, and includes all image sources in multiple resolutions and formats needed to create a fully responsive image with lazy-loading, blur-up and low-resolution placeholders.This is primarily for plugins that provide their own URLs for resized images. Plugins that use sharp for resizing do not need to make any changes, as the new resolvers will be added automatically.
We are also adding a custom hook that allows runtime generation of gatsby image data, meaning these can be used in situations where the image data is loaded at runtime rather than build time. While this loses the benefit of the low-resolution placeholder, it does allow many of the benefits of the component in situations where they were not previously available.
There are three new exports added to
gatsby-plugin-image
:generateImageData
This is the core helper function, which is used by the other helpers, and you would not normally use it on its own. It takes a set of options and returns a
GatsbyImageData
object which can be passed directly to aGatsbyImage
component. The most important parameter is thegenerateImageSource
callback function, which allows the source plugin to generate the custom URLs, when given an image, dimensitons and format. A simple example would be:It returns a width, height and format as well as the URL, because it can override the requested format. This might happen if the requested size is too large, for example, or if the format is unsupported.
The rest of the options are mostly passed-through directly. A minimal example could be:
A more comprehensive example can be seen in the
getGatsbyImageFieldConfig
resolver below.This helper is available at both compile time and runtime, but you must be careful to not perform any expensive operations at runtime. In those cases you should use it at compile time, by adding a custom resolver as shown below.
getGatsbyImageFieldConfig
This helper function is designed to make it easier to add a
gatsbyImageData
resolver to a source plugin. It is imported from"gatsby-plugin-image/graphql-utils"
. As it is run at compile time, you can include async, expensive operations such as downloading base64-encoded preview images. The returned field config includes all the arguments needed by the helper, including width, height, maxWidth, maxHeight, layout, formats etc. The fields are pre-defined with descriptions, and you can also pass additional definitions for custom arguments. Usage is like this:For a full example, see this PR for Contentful, which adds a resolver for
gatsbyImageData
.useGatsbyImage
This is a custom hook which can be used at runtime, designed to be used to create more specialised hooks targeting specific image hosts. It should be used when you can deterministically create a URL based on the requested parameters, such as with an image host like Cloudinary. It should be used in cases where no pre-processing needs to happen at compile time. Bear in mind that this means you cannot create placeholder images such low-res blurred or traced SVG images. The big deal here is that it can work with fully dynamic image URLs. Usage is as follows:
For a full example, see this custom hook for Cloudinary
Which should I use?
Ideally you should use the custom resolver, as it is the only way to include a placeholder image that displays without network access. This gives the best performance and user experience. However that is not always possible. The custom hook can be used in situation where the image URL is dynamically loaded at runtime, such as for search results or live data from an external source. In these situations, setting a background color is a good way to provide a good loading experience. If you control the API, consider providing a "dominant color" property alongside your image URLs, which allows you to provide an even better experience.
getGatsbyImageFieldConfig
and generate them at build time.getGatsbyImageFieldConfig
and make a PR to update the gatsby image codemod to support your plugin.useGatsbyImage
[ch19256]