Uploading files can sometimes be a complex thing when using JavaScript. In the previous tutorials, we have built a way to update settings and show a notice on that. In this tutorial, we will upload an avatar for the user.

If you’ve just came to this tutorial before going through the other ones, consider reading them (or copy the code):

  1. Logging with JWT
  2. Updating Settings
  3. Notices System

In WordPress, the avatar is returned from a function get_avatar which returns the HTML for it. Also, when we retrieve the data, the avatar_urls are from the service gravatar. We could filter them out, but let’s learn more about using the user meta with REST API.

Check the video in this tweet on how this will look like.

Registering User Meta

To store our newly uploaded avatar images, we will use the meta key avatar. This will contain the URL to it. To be able to update such meta, we need to register them so it can be used with the REST API.

Create a new file under wp-content/plugins and call it whatever you like. Then add this:

Activate the plugin and you will now have this meta registered so it can be returned by REST API and also updated with REST API.

The avatar ID can be used for some other cases if we need to know which attachment ID it is.

Displaying the User Image

Let’s now create a function that will be used to display the image of the user. Create a new file under the folder functions in our React app and name it user.js.

Since the meta that is returned from the REST API is always shown as an array, we will check if we have the avatar meta. If it is there, we will return the first item of that array.

If there is no such data, we will check for avatar_urls. If there is an image, we then show the image.

Let’s now try displaying that image in our dumb component Profile which is currently defined under src/components/Dashboard.js.

We are importing this function getImage and then we pass the user object to it so we can show the image.

Uploading the User Image

Now that we have a way to show the image, let’s also create a way to upload it. We will need a function that will handle file uploads. This function will have the JavaScript File object and send it to our server as FormData.

Open again the functions/user.js file and add this function to it:

This function createMediaFromFile is accepting the file, additional data, user token and the url of the site. We are then creating an axios post call to the wp-json/wp/v2/media. In case this is is not possible with regular user accounts, you can use a custom AJAX or REST route to handle uploads.

Let’s now go to our settings component under src/components/dashboard/Settings.js and update it.

We are importing the new components DropZoneProvider and DropZone from @wordpress/components. We are also importing the functions getImage and createMediaFromFile.

Before using the DropZone component, we will have to create a function to handle file uploads.

We are binding that new function fileUpload to this so that we can access the state from it. We then iterate through each file in files and try to upload it.

If it has been uploaded, we then update our state. The update object has the new avatar meta set under meta object. Here, we just set it directly to the value, without needed to create an array out of the avatar value. But for the user object, we need to update the meta as if we were getting that information from the REST API (as array).

Let’s now add the DropZone component. You can read about all the properties of it, in the repository.

We are wrapping it with the DropZoneProvider. This will make the DropZone component show inside of it. We are then showing the current image of the user and also pass the fileUpload function to the onFilesDrop property of the component.

Once we hit the update button, we will perform an update on the current user and the meta will be updated. If you’re going to use this in production, please:

  • check for file type so that only images are uploaded,
  • delete the old avatars when the new one is updated
  • delete the new avatars if the user did not update it.

The current style will render the whole upload area as the whole window, but we need to maintain it within the DropZone provider, so add this to App.scss.


To get the complete code, you can download it here. Be sure to run npm install to get all the node modules so you can work on it.

This part is available only to the members. If you want to become a member and support my work go to this link and subscribe: Become a Member


With such DropZone components (and alike) we can create great user experiences with ease and within minutes. By adding our own upload routes, you can define how and where the files are uploaded.

Become a Sponsor

Posted by Igor Benic

Web Developer who mainly uses WordPress for projects. Working on various project through Codeable & Toptal. Author of several ebooks at https://leanpub.com/u/igorbenic.

Leave a reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.