Recently at work I integrated the famous service to manage avatar: Gravatar
This service is very useful, because with only one configuration we can have the same avatar in different places.
So, let's go into the deep for integrating Gravatar on React application using tanstack query.
Prerequisites:
- React
- Tanstack query
- Valibot
First of all, we analyze how to get avatar image from Gravatar. Here the official doc:
https://docs.gravatar.com/api/avatars/images/
We have a lot of configurations, but for us are importants 3 things:
- Email Hash (MD5 or SHA256)
- Default parameter
- Json format
Email Hash
With this we can get the avatar image. Just call this url with email hashed
For example:
https://gravatar.com/avatar/27205e5c51cb03f862138b22bcb5dc20f94a342e744ff6df1b8dc8af3c865109
So we know that if we call this url we obtain the avatar. Cool.😎
But, if I don't have any account on Gravatar, how can manage this situation?
Let's see the default parameter
Default parameter
Gravatar offer differents parameters for our url. One of this is d=404
d
means default and 404
is the famous error. So if we don't have any account on Gravatar the url will response with Not found
.
So the url will be something like that:
https://gravatar.com/avatar/27205e5c51cb03f862138b22bcb5dc20f94a342e744ff6df1b8dc8af3c865109?d=404
Json format
If we want more information on this Gravatar account we can add the json extension on url. For example in my case I added this:
https://gravatar.com/avatar/27205e5c51cb03f862138b22bcb5dc20f94a342e744ff6df1b8dc8af3c865109.json?d=404
This will return an specific json structure with also the avatar url.
More info here: https://docs.gravatar.com/api/profiles/json/
Code
Let's look the code
Create schema validation with Valibot
import { array, object, string, type Output } from "valibot";
export const GravatarSchema = object({
entry: array(
object({
photos: array(
object({
value: string(),
})
),
})
),
});
export type GravatarSchema = Output<typeof GravatarSchema>;
Make the api call with Tanstack Query
import { GravatarSchema } from '@/types';
import { gravatarClient } from '@/utils';
export const getAvatar = async (emailHash: string) =>
gravatarClient.get(`/${emailHash}.json?d=404`, GravatarSchema);
Here we can use the md5 library to generate email hash or sha256 if we want be safe.
const { data, isError } = useQuery({
queryKey: ['getAvatar', username],
queryFn: () => getAvatar(md5(username))
});
Check if we have an error and we show the fallback icon or we show the avatar.
<div className="mr-4">
<Avatar>
{!isError ? (
<AvatarImage
className="rounded-b-lg"
src={data?.entry
.flatMap((item) => item.photos.map((photo) => photo.value))
.at(0)}
alt={username}
/>
) : (
<AvatarImage className="bg-gray p-1" src={UserIcon} alt="avatar-fallback" />
)}
</Avatar>
</div>
And that's it.
See you next time. ✨
Top comments (0)