Optimizing Gravatars in Gatsby

How to pass Gravatar images through gatsby-image’s awesome optimizations.

Kaleab S. Melkie
The Startup
Published in
4 min readMar 9, 2020


NOTE: This article assumes you have a basic understanding of React and Gatsby.

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:

Code for Method 1: Remote, Dynamic, Fast-ish

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 in GatsbyImage.

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:

  1. We get our Gravatars’ URLs into Gatsby’s running node using gatsby-source-gravatar,
  2. We turn those image URLs in the nodes to actual local file copies using gatsby-plugin-remote-images, and
  3. 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:

Code for gatsby-config.js

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 urls 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:

Code for Method 2: Local, Static, Really Fast

Now we have a static but really fast Gravatar that is optimized using gatsby-image.

Full Source Code

CodeSandbox | Github Repo