Recently Justin Tadlock posted on the WP Tavern about the WordPress Privacy teams plans for local avatars in WordPress to improve privacy options in core WordPress.
I’ve been thinking about making my own avatar system for years. I like doing creative things, and I thought making an attractive avatar replacement would be fun.
By default WordPress comes with a bunch of generated avatars (MonsterID, Wavatar, Identicon, Retro) that are unique for each user, but these are ugly and indistinct.
I wanted to make something a bit more attractive, and more unique. The result has now been added to the Toolbelt plugin.
Privacy
Initially I wanted to do this as a creative exercise. I hadn’t considered the privacy aspects of this change but it makes total sense.
All WordPress avatars are generated at Gravatar.com. Including the generic filler ones for users who don’t have accounts. This means that Gravatar could potentially track users around the web. Including people who don’t have accounts. Gravatar might not know who people are but they could learn a lot by following where people comment, or post.
They could also use image loads as a method of counting page impressions, and the number of avatars on a page as a way to gauge content/ website popularity. There’s a lot of statistics that could be gleaned from looking at how the images around the web.
I should add that I very much doubt they are doing this stuff. But the potential for it to be done is there.
In addition, Gravatar uses an md5 hash to generate the avatars. This is pretty easy to crack, and for many people this could be problematic.
Speed & Anything else?
Besides privacy, hosting images on a third party domain has speed implications. If you have hundreds of comments then the extra work of loading all the avatars will cause a performance hit, no matter how good the CDN the images are loaded from.
A Solution
What started out as a fun creative project turned into an attempt to fix these issues.
Originally I was going to make the avatars in PHP, much like the default avatars are. But I decide instead to make them with Javascript and craw on a canvas.
How are the avatars made
To make the avatars I use a series of shapes and colours. The face is split into head shape, body, hair, and mouth. For each of these items I pick a shape to use from the available list, and a colour to use, and then combine them all.
The colours use hsl colour mode. This means I can select the saturation and lightness manually, and alter the hue per shape. I want control over the lightness in particular so that I can ensure there is consistent contrast between the different shapes. For example we need to make sure the mouth shape is darker than the face shape so that it is always visible.
Each shape has the ability to use one of 2 shades of the chosen colour,vthe base colour and a darker version (generated automatically by darkening the lightness in the hsl color), black and white. This allows for some variation in the shapes and consistency in the colours.
The shapes and colours chosen are not random. For each user I create a short hash string using the email address and then I use the characters from the string in sequence. The first character in the string is the colour of the background. The second character in the string is the colour of the face, the third character is the shape of the face, and so on.
Because the hash is tied to the users email address it will be consistent across websites and so you will always get the same avatar when you comment in different places.
The code for the avatar creation is small and efficient. It’s less than 5kb, which is less than the size of one Gravatar image. Plus, because the avatars are drawn on canvases locally, there’s no phoning out to third party sites. Everything happens in the browser so it’s super fast.
Can I use it?
I’ve now turned this into a plugin and added it to Toolbelt, my privacy and speed focused alternative to Jetpack.
The code for the plugin is on Github.
I’m running the new Pixel avatars on this site and they seem to be working well. There may be a few teething issues, or things I haven’t considered (most likely in the wp-admin) but mostly it’s been quite an easy change.
If you do find any problems then I would really appreciate a comment here, or a tweet, or an issue on Github, or whatever.
Was it good/ useful/ a load of old rubbish? Let me know on Mastodon, or BlueSky (or Twitter X if you must).
Link to this page
Thanks for reading. I'd really appreciate it if you'd link to this page if you mention it in your newsletter or on your blog.