We upload our profile pictures once on Gravatar, link it to our email addresses and it follows us on the Internet when we sign up and view our accounts on systems that support it. It’s a neat feature to have even in statically generated Gatsby websites for users (or you, perhaps in your company’s About page).
The Problem
Most images in Gatsby are preprocessed by a library called gatsby-image. For this library to work its magic in full effect, we need either:
- The image in our local file system,
- Or the remote image URL as a value somewhere in Gatsby’s GraphQL node.
With normal Gravatar usage, the image is served directly from Gravatar servers and is not processed by the awesome gatsby-image whatsoever. Having a site built with Gravatar, usually, everything loads so fast and the Gravatar images are the performance bottlenecks, especially when tested by systems like Lighthouse.
I understand that Gravatar provides its image resizing feature, but it’s nothing compared to gatsby’s image on-demand WebP support, on-scroll lazy loading, aggressive caching, traced SVG placeholder support, compression, and overall optimizations. So below we’ll see two scenarios with different requirement needs for integrating Gravatar images in Gatsby (specifically gatsby-image).
Method 1: Remote, Dynamic, Fast-ish
The first case is when we need Gravatars to load-on-demand, in situations such us where we don’t know the Gravatar emails ahead of time during the development process.
In this case, assuming we already have a Gatsby project setup with gatsby-image, we add a plugin called gatsby-source-gravatar:
yarn add gatsby-source-gravatar
Next, we import toUrl
from this library into our components to convert the emails into Gravatar URLs dynamically at any given time.
Here’s what it looks like:
Here, the useMemo
React hook is used only for performance optimization but is not necessary. The most important pieces of this code are:
- The
toUrl
call to get a Gravatar URL from an email address, and - How the
url
is used manually inGatsbyImage
.
In the above usage of gatsby-image, we configured the 'fluid'
option, manually. We set options such as src
, srcSet
and sizes
. For the different sizes needed we use Gravatar’s image resizing options using queries like: `${url}?size=512`
.
This method, however, does not give us the full feature set of gatsby’s image optimizations. We get lazy loading and fluid aspect ratios but miss out on on-demand WebP support, Traced SVG placeholders and so on.
This means that this manual gatsby-image definition method is not always as fast as the recommended way of the library’s implementation and can be particularly hard if you don’t have different sizes and/or formats of your images defined in your remote URL. However, for this trade-off, you get to use some features of the library for your dynamic images (in our case, the Gravatars).
Method 2: Local, Static, Really Fast
If you know the emails you need for your Gravatars ahead-of-time and don’t mind the images being generated just once during build time, there is a better alternative to the approach discussed earlier in Method 1.
In this method, we will use a library called gatsby-plugin-remote-images, in addition to the previous gatsby-source-gravatar. So let’s install them.
yarn add gatsby-source-gravatar gatsby-plugin-remote-images
The general idea of this method is as simple as these three steps:
- We get our Gravatars’ URLs into Gatsby’s running node using gatsby-source-gravatar,
- We turn those image URLs in the nodes to actual local file copies using gatsby-plugin-remote-images, and
- Use gatsby-image like we normally would with a local image file, and get its full optimization feature-set.
For the first step, we need to configure our [ahead-of-time-known] email addresses in gatsby-config.js
as an option of our gatsby-source-gravatar
plugin.
As for the second step, we configure gatsby-plugin-remote-images
in gatsby-config.js
to point to the URL nodes generated by our gatsby-source-garavatar
plugin from the previous step.
Here is what gatsby-config.js
should generally look like, after the first two steps:
Here, gatsby-source-gravatar adds a node named “gravatar” (which can be queried using allGravatar
or just gravatar
with options). In the result object of this query, there will be a url
string, for each email address provided. So gatsby-plugin-remote-address
is configured to access these url
s from the gravatar
nodes.
Step 2 generates a child node inside thegravatar
type, called localImage
by default. localImage
is accessible in Gatsby queries besides url
and can be used to query what’s needed for gatsby-image.
So for the final step, we just query the image from gravatar.localImage
, as shown below:
Now we have a static but really fast Gravatar that is optimized using gatsby-image.