UsersWP

WordPress profile picture. How to change avatar via Gravatar, a plugin, or custom code. (Full Tutorial)

Everyone developing WordPress websites, sooner or later, will face the need to change a user’s profile picture. That’s when they discover that inside WordPress, there is no way to do so.

If you are in the situation right now to ask yourself: How do I change my profile picture on WordPress? Here you’ll find all the possible answers.

There are 3 ways to do:

  1. Through Gravatar.com, which is the Standard WP way
  2. Using a WordPress plugin
  3. With custom code to be added to your theme’s functions.php

Before jumping into the tutorial, let’s clear up everything about the WordPress user’s profile picture aka the WP Avatar.

What is WordPress Avatar?

The WordPress default Avatar

The WP avatar is a user’s profile picture on a WordPress website.

It normally appears next to each comment, but depending on the theme used, it can also be used displayed at the end of posts to highlight the author.

If you are using bbPress or BuddyPress, the avatar will be visible next to each forum thread or reply and activity post.

By default, WordPress uses a pre-defined avatar for all users and as I previously mentioned, inside WordPress, there is no way to change it.

Even the pre-defined Avatar, does not live on your server.

Instead, it is loaded through gravatar.com, a site owned by Automattic, the company behind WordPress.com.

How to change profile picture on WordPress via Gravatar.com?

the standard way that WordPress provides, to change a profile picture (without a plugin or custom code) is to head to Gravatar.com.

You’ll need to connect a WordPress.com account (yes you will need that 1st to signup), and create an account to upload your gravatar.

A Gravatar, which stands for Globally Recognized Avatar, is a profile picture associated with an email address on Gravatar.com.

Your gravatar will be used whenever you write a comment, a forum post, or a blog post on any WordPress powered site.

This is valid for both WordPress.com blogs and self-hosted WordPress websites.

A global avatar sounds like an awesome feature, so why would someone want to simply upload their own avatar on their server?

There may be several reasons, but the 3 most important probably are:

How to change profile picture on WordPress via plugin?

there are several plugins that will allow your users to change their profile picture on your WordPress website.

However, most of them will do a lot more than that and you might not need some or most of their features.

A lot of them allow you to set a rating for the picture, which can be useful if you are loading the avatar from remote like with gravatar.com.

But it’s not indispensable if you are loading the profile pictures from your local server.

Many others will give the option to upload the avatar from the front end too. A nice feature, but if you just need your authors to change their profile picture, probably that’s not needed because authors should already have access to the WP backend.

The only plugin that I’ve found that only allow to upload a custom avatar locally and does it in a simple way is the Simple User Avatar plugin.

Wp Simple Avatar plugin

This plugin does almost exactly what the code in our tutorial below does.

The main difference is that our code is extremely lightweight with less than 100 lines of code (without comments).

The Simple User Avatar plugin will add approximately twice as many lines of code (between PHP, CSS, and JS).

Other than that, this plugin doesn’t allow to replace the default avatar and it will not prevent loading the default avatar from gravatar.com.

That said, it is by far the most simple and lightweight plugin on the WordPress.org plugin repository to manage avatars.

If you don’t have a problem adding yet another plugin on your install to get users to change their profile picture and you need just that, I’d suggest going with The Simple User Avatar plugin.

If instead, you want some modern code to add to your theme without extra frills and you want to solve all problems related to loading avatars via gravatar.com and forget about updates… the following code is what you are looking for.

How to change profile picture on WordPress with custom code?

Finally, we get to our tutorial.

We wrote this code using WordPress best practices and we’ll use the standard media uploader that ships with WordPress and nothing else.

The following code can be added to your theme’s functions.php file or if you are already using the code snippets plugin, on a new code snippet.

Let’s get started!

1) First of all, we need to enqueue the Media Uploader scripts. It’s important to load it only on the profile page. We add the function using the action admin_enqueue_scripts.

/**
 * Custom Avatar Without a Plugin
 */
// 1. Enqueue the needed scripts.
add_action( "admin_enqueue_scripts", "ayecode_enqueue" );
function ayecode_enqueue( $hook ){
	// Load scripts only on the profile page.
	if( $hook === 'profile.php' || $hook === 'user-edit.php' ){
		add_thickbox();
		wp_enqueue_script( 'media-upload' );
		wp_enqueue_media();
	}
}

2) Next, we need to create the function to use the media uploader scripts inside the edit profile page of WordPress. We add our function using the action admin_print_footer_scripts-profile.php and admin_print_footer_scripts-user-edit.php.

// 2. Scripts for Media Uploader.
function ayecode_admin_media_scripts() {
	?>
	<script>
		jQuery(document).ready(function ($) {
			$(document).on('click', '.avatar-image-upload', function (e) {
				e.preventDefault();
				var $button = $(this);
				var file_frame = wp.media.frames.file_frame = wp.media({
					title: 'Select or Upload an Custom Avatar',
					library: {
						type: 'image' // mime type
					},
					button: {
						text: 'Select Avatar'
					},
					multiple: false
				});
				file_frame.on('select', function() {
					var attachment = file_frame.state().get('selection').first().toJSON();
					$button.siblings('#ayecode-custom-avatar').val( attachment.sizes.thumbnail.url );
					$button.siblings('.custom-avatar-preview').attr( 'src', attachment.sizes.thumbnail.url );
				});
				file_frame.open();
			});
		});
	</script>
	<?php
}
add_action( 'admin_print_footer_scripts-profile.php', 'ayecode_admin_media_scripts' );
add_action( 'admin_print_footer_scripts-user-edit.php', 'ayecode_admin_media_scripts' );

3) Now we need to add the custom image section for the avatar to the edit profile page of WordPress. We add our function using the action show_user_profile and edit_user_profile.

// 3. Adding the Custom Image section for avatar.
function custom_user_profile_fields( $profileuser ) {
	?>
	<h3><?php _e('Custom Local Avatar', 'ayecode'); ?></h3>
	<table class="form-table ayecode-avatar-upload-options">
		<tr>
			<th>
				<label for="image"><?php _e('Custom Local Avatar', 'ayecode'); ?></label>
			</th>
			<td>
				<?php
				// Check whether we saved the custom avatar, else return the default avatar.
				$custom_avatar = get_the_author_meta( 'ayecode-custom-avatar', $profileuser->ID );
				if ( $custom_avatar == '' ){
					$custom_avatar = get_avatar_url( $profileuser->ID );
				}else{
					$custom_avatar = esc_url_raw( $custom_avatar );
				}
				?>
				<img style="width: 96px; height: 96px; display: block; margin-bottom: 15px;" class="custom-avatar-preview" src="<?php echo $custom_avatar; ?>">
				<input type="text" name="ayecode-custom-avatar" id="ayecode-custom-avatar" value="<?php echo esc_attr( esc_url_raw( get_the_author_meta( 'ayecode-custom-avatar', $profileuser->ID ) ) ); ?>" class="regular-text" />
				<input type='button' class="avatar-image-upload button-primary" value="<?php esc_attr_e("Upload Image","ayecode");?>" id="uploadimage"/><br />
				<span class="description">
					<?php _e('Please upload a custom avatar for your profile, to remove the avatar simple delete the URL and click update.', 'ayecode'); ?>
				</span>
			</td>
		</tr>
	</table>
	<?php
}
add_action( 'show_user_profile', 'custom_user_profile_fields', 10, 1 );
add_action( 'edit_user_profile', 'custom_user_profile_fields', 10, 1 );

4) We also need a function to save the values in the database. We add our function using the action personal_options_update and edit_user_profile_update.

// 4. Saving the values.
add_action( 'personal_options_update', 'ayecode_save_local_avatar_fields' );
add_action( 'edit_user_profile_update', 'ayecode_save_local_avatar_fields' );
function ayecode_save_local_avatar_fields( $user_id ) {
	if ( current_user_can( 'edit_user', $user_id ) ) {
		if( isset($_POST[ 'ayecode-custom-avatar' ]) ){
			$avatar = esc_url_raw( $_POST[ 'ayecode-custom-avatar' ] );
			update_user_meta( $user_id, 'ayecode-custom-avatar', $avatar );
		}
	}
}

5) Finally, we set the uploaded image as the users’ avatar, and for users without an uploaded image, we’ll use a local avatar that we created. We add our function using the filter get_avatar_url.

// 5. Set the uploaded image as default gravatar.
add_filter( 'get_avatar_url', 'ayecode_get_avatar_url', 10, 3 );
function ayecode_get_avatar_url( $url, $id_or_email, $args ) {
	$id = '';
	if ( is_numeric( $id_or_email ) ) {
		$id = (int) $id_or_email;
	} elseif ( is_object( $id_or_email ) ) {
		if ( ! empty( $id_or_email->user_id ) ) {
			$id = (int) $id_or_email->user_id;
		}
	} else {
		$user = get_user_by( 'email', $id_or_email );
		$id = !empty( $user ) ?  $user->data->ID : '';
	}
	//Preparing for the launch.
	$custom_url = $id ?  get_user_meta( $id, 'ayecode-custom-avatar', true ) : '';
	
	// If there is no custom avatar set, return the normal one.
	if( $custom_url == '' || !empty($args['force_default'])) {
		return esc_url_raw( 'https://ayecode.b-cdn.net/wp-content/uploads/sites/12/2020/07/blm-avatar.png' ); 
	}else{
		return esc_url_raw($custom_url);
	}
}

That’s it, if you want the whole code to just copy and paste, you can find it here. Props to our dev Laranz for it :

/**
 * Custom Avatar Without a Plugin
 */

// 1. Enqueue the needed scripts.
add_action( "admin_enqueue_scripts", "ayecode_enqueue" );
function ayecode_enqueue( $hook ){
	// Load scripts only on the profile page.
	if( $hook === 'profile.php' || $hook === 'user-edit.php' ){
		add_thickbox();
		wp_enqueue_script( 'media-upload' );
		wp_enqueue_media();
	}
}

// 2. Scripts for Media Uploader.
function ayecode_admin_media_scripts() {
	?>
	<script>
		jQuery(document).ready(function ($) {
			$(document).on('click', '.avatar-image-upload', function (e) {
				e.preventDefault();
				var $button = $(this);
				var file_frame = wp.media.frames.file_frame = wp.media({
					title: 'Select or Upload an Custom Avatar',
					library: {
						type: 'image' // mime type
					},
					button: {
						text: 'Select Avatar'
					},
					multiple: false
				});
				file_frame.on('select', function() {
					var attachment = file_frame.state().get('selection').first().toJSON();
					$button.siblings('#ayecode-custom-avatar').val( attachment.sizes.thumbnail.url );
					$button.siblings('.custom-avatar-preview').attr( 'src', attachment.sizes.thumbnail.url );
				});
				file_frame.open();
			});
		});
	</script>
	<?php
}
add_action( 'admin_print_footer_scripts-profile.php', 'ayecode_admin_media_scripts' );
add_action( 'admin_print_footer_scripts-user-edit.php', 'ayecode_admin_media_scripts' );


// 3. Adding the Custom Image section for avatar.
function custom_user_profile_fields( $profileuser ) {
	?>
	<h3><?php _e('Custom Local Avatar', 'ayecode'); ?></h3>
	<table class="form-table ayecode-avatar-upload-options">
		<tr>
			<th>
				<label for="image"><?php _e('Custom Local Avatar', 'ayecode'); ?></label>
			</th>
			<td>
				<?php
				// Check whether we saved the custom avatar, else return the default avatar.
				$custom_avatar = get_the_author_meta( 'ayecode-custom-avatar', $profileuser->ID );
				if ( $custom_avatar == '' ){
					$custom_avatar = get_avatar_url( $profileuser->ID );
				}else{
					$custom_avatar = esc_url_raw( $custom_avatar );
				}
				?>
				<img style="width: 96px; height: 96px; display: block; margin-bottom: 15px;" class="custom-avatar-preview" src="<?php echo $custom_avatar; ?>">
				<input type="text" name="ayecode-custom-avatar" id="ayecode-custom-avatar" value="<?php echo esc_attr( esc_url_raw( get_the_author_meta( 'ayecode-custom-avatar', $profileuser->ID ) ) ); ?>" class="regular-text" />
				<input type='button' class="avatar-image-upload button-primary" value="<?php esc_attr_e("Upload Image","ayecode");?>" id="uploadimage"/><br />
				<span class="description">
					<?php _e('Please upload a custom avatar for your profile, to remove the avatar simple delete the URL and click update.', 'ayecode'); ?>
				</span>
			</td>
		</tr>
	</table>
	<?php
}
add_action( 'show_user_profile', 'custom_user_profile_fields', 10, 1 );
add_action( 'edit_user_profile', 'custom_user_profile_fields', 10, 1 );


// 4. Saving the values.
add_action( 'personal_options_update', 'ayecode_save_local_avatar_fields' );
add_action( 'edit_user_profile_update', 'ayecode_save_local_avatar_fields' );
function ayecode_save_local_avatar_fields( $user_id ) {
	if ( current_user_can( 'edit_user', $user_id ) ) {
		if( isset($_POST[ 'ayecode-custom-avatar' ]) ){
			$avatar = esc_url_raw( $_POST[ 'ayecode-custom-avatar' ] );
			update_user_meta( $user_id, 'ayecode-custom-avatar', $avatar );
		}
	}
}


// 5. Set the uploaded image as default gravatar.
add_filter( 'get_avatar_url', 'ayecode_get_avatar_url', 10, 3 );
function ayecode_get_avatar_url( $url, $id_or_email, $args ) {
	$id = '';
	if ( is_numeric( $id_or_email ) ) {
		$id = (int) $id_or_email;
	} elseif ( is_object( $id_or_email ) ) {
		if ( ! empty( $id_or_email->user_id ) ) {
			$id = (int) $id_or_email->user_id;
		}
	} else {
		$user = get_user_by( 'email', $id_or_email );
		$id = !empty( $user ) ?  $user->data->ID : '';
	}
	//Preparing for the launch.
	$custom_url = $id ?  get_user_meta( $id, 'ayecode-custom-avatar', true ) : '';
	
	// If there is no custom avatar set, return the normal one.
	if( $custom_url == '' || !empty($args['force_default'])) {
		return esc_url_raw( 'https://ayecode.b-cdn.net/wp-content/uploads/sites/12/2020/07/blm-avatar.png' ); 
	}else{
		return esc_url_raw($custom_url);
	}
}

We also changed all default Gravatars with a locally uploaded avatar

With the last block of code, we also changed the default Mystery Man Avatar with a custom avatar that we uploaded locally.

We created this one for the occasion. (to show our support to the Black Lives Matter movement)

The BLM Avatar

Make sure to modify the bold part of this line with the URL of your custom avatar:

return esc_url_raw( '<strong>https://userswp.io/wp-content/uploads/sites/12/2020/07/blm-avatar.png</strong>' );

Should you need more than just allowing your users to change their profile pictures, like full-blown and customizable user profiles, users directory, and many other features, we suggest looking into our UsersWP plugin.

It is the most lightweight and sleek looking Users Profile Plugin for WordPress.

Questions? If you have any, don’t hesitate to ask in the comments down below!