Stop sending every user's email to a third party just to show an avatar
Local Avatar lets every logged-in user, including roles with no media library access, upload their own profile picture stored directly on the site — replacing Gravatar everywhere an avatar appears, with an option to eliminate outbound requests to gravatar.com entirely.
- Available to every role, even those without upload_files.
- Replaces Gravatar site-wide, automatically, everywhere get_avatar() is used.
- Optional fully local initials placeholder, zero external requests.
- Keeps up to 8 previous uploads, selectable again without re-uploading.
Profile Picture
JPG, PNG, GIF or WebP.
What does Local Avatar do?
When the local_avatar module is active, TOWP_Local_Avatar adds a picture upload field to every user's own profile screen, available even to roles like Subscriber or Contributor that normally can't use the media library at all. The uploaded image gets stored as a regular attachment and picked up automatically everywhere WordPress or another module calls get_avatar(), via the pre_get_avatar_data filter, so nothing elsewhere in the site needs to change. With Gravatar's fallback disabled, anyone without a local avatar gets a deterministic, locally generated initials placeholder instead, an inline SVG with no file and no external request at all.
Every avatar on the site quietly phones Gravatar
Since Gravatar is WordPress's default avatar source, most sites send this request without anyone deciding that was the right tradeoff.
An email hash goes out on every page that shows a face
By default, WordPress sends a hash of a user's email address to Gravatar's servers on every single page that displays an avatar, whether that user ever signed up there or not.
Most people never signed up, so they just get a generic icon anyway
The request still goes out even for someone who never created a Gravatar account, and all that's shown in return is a default placeholder, not an actual picture.
A real face, stored where the site already is
The module replaces the external lookup with a picture stored locally, available to every role and picked up automatically wherever an avatar already appears.
Available to every role
Even a Subscriber or Contributor, roles with no access to the media library otherwise, can upload their own picture from their profile screen.
Replaces Gravatar everywhere automatically
Every existing call to get_avatar() across WordPress core and other modules picks up the local picture without any code changes elsewhere.
An option to stop the external request entirely
With Gravatar's fallback disabled, anyone without a local picture gets a locally generated placeholder instead, no request to gravatar.com at all.
Local by default, verified at every step
Every capability below is present in the supplied PHP class and its settings registration.
pre_get_avatar_data covers every call
A single filter intercepts every get_avatar() and get_avatar_url() call throughout WordPress core and any other module, so a local picture appears everywhere automatically.
A deliberate carve-out for every role
The profile upload field works for any logged-in user, including roles that can't otherwise upload anything to the media library at all.
Switch back without re-uploading
Past uploads stay selectable from a gallery on the profile screen, with the oldest surplus automatically pruned once the limit is reached.
An inline SVG, no file, no request
When Gravatar's fallback is disabled, a deterministic colored-initial SVG gets generated as a data URI, the same person always getting the same color.
Selecting or deleting checks who actually uploaded it
A dedicated ownership meta field gets checked before any history item can be selected or deleted, protecting against a tampered request.
Extension, MIME and actual image content, all checked
An uploaded file is restricted by extension and MIME type, then independently confirmed to be a genuinely readable image before it's ever registered.
Where local avatars help most
The module supports any site that would rather not depend on an external avatar service.
Privacy-conscious sites that don't want emails leaving the server
Stop sending a hash of every user's email address to a third party just to render an avatar.
Membership or community sites where every role should look real
Let subscribers, members and contributors add a real picture, not just staff-level roles with media access.
Comment sections and chat features that already call get_avatar()
Get consistent, local avatars in every existing avatar-driven feature without touching that feature's own code.
Less exposure, more presence
The module combines a genuine privacy improvement with a more personal-feeling profile for every role.
One lookup, or nothing at all
The verified implementation stays lightweight whether a picture exists or not.
One filter check per avatar request
Resolving the picture is a single user-meta lookup and an attachment check, no heavier than any other avatar-rendering logic.
No file, no request for the placeholder option
The initials placeholder is generated inline as a data URI; there's no image file to store and no network request to make.
History capped, so it never grows unbounded
The 8-item history limit keeps the number of stored avatar attachments per user under control automatically.
Verified, owned, and logged
The code validates every upload thoroughly and checks ownership before every action.
File type restricted, then independently verified
An upload gets checked against an explicit MIME allowlist, then confirmed with getimagesize() to catch a disguised file that slipped past the extension check.
Every action requires editing that specific user
Both uploading and managing history require current_user_can('edit_user', $user_id), the same check whether it's a user editing their own profile or an admin editing someone else's.
Ownership checked before every select or delete
A hidden field tampered with client-side can't be used to select or delete another user's avatar history, since ownership gets verified server-side first.
Every action logged
Uploads, selections, removals, deletions and even failures get recorded through the audit log.
Built directly around WordPress's own avatar and upload APIs
The supplied code integrates through APIs present in WordPress core; this page makes no compatibility claim beyond the verified implementation.
pre_get_avatar_data
The native WordPress filter used to intercept and override avatar resolution before WordPress falls back to Gravatar.
wp_handle_upload() and wp_insert_attachment()
The same core functions WordPress itself uses for any file upload, applied here to a user's own profile picture.
user_edit_form_tag
The native hook used to add multipart form encoding to the profile screen, which doesn't have it by default since WordPress never expected a file upload there.
TheOneWP versus common alternatives
Compare the verified Local Avatar implementation with a typical media-library-only upload approach.
| Capability | TheOneWP Local Avatar | Other common solutions |
|---|---|---|
| Who can upload a picture | Every logged-in role, media library access or not | Often limited to roles that already have upload_files |
| Replacing Gravatar everywhere | One filter, automatic for every existing avatar call | Some approaches require updating each avatar-displaying feature individually |
| Eliminating external requests entirely | A fully local, deterministic placeholder option | Frequently still falls back to Gravatar for anyone without a picture |
| File validation | MIME allowlist plus independent image-content verification | Some approaches trust the file extension alone |
| Avatar history | Up to 8 previous pictures, selectable again | Usually only the single current picture is kept |
Add local avatars in four steps
Decide on the Gravatar fallback setting first, since it shapes what everyone without a picture sees.
Enable Local Avatar
Activate the module from the TheOneWP Backend settings tab.
Decide whether to disable the Gravatar fallback
Turn it off if the goal is eliminating outbound requests entirely, or leave it on to keep Gravatar as a fallback for users without a local picture.
Upload a picture from the profile screen
Visit any user's profile screen and use the Profile Picture field to choose an image.
Confirm it appears wherever avatars are shown
Check comments, chat, or any other avatar-driven feature to confirm the picture appears automatically.
Decide the privacy stance deliberately
The Gravatar fallback setting is the single decision that shapes the module's overall privacy impact.
Disable the Gravatar fallback for the strongest privacy stance
Turning it off removes every remaining outbound request, not just the ones for users who already uploaded a picture.
Encourage uploads for roles that interact with visitors
A real picture next to a name adds recognition value for any role customers or members regularly see, like support staff or moderators.
Let the history gallery handle picture changes
Switching back to a previous picture through the gallery avoids uploading the same file again.
Review the audit log after a bulk profile update
Since every avatar action gets logged, the audit log is the fastest way to confirm what changed across many accounts.
Avoid a couple of details that are easy to misread
A few behaviors are easy to assume incorrectly the first time through.
Assuming Remove deletes the picture entirely
Removing the current avatar only clears which picture is active; the file itself stays in the history gallery for later reuse.
Expecting the placeholder without disabling the Gravatar fallback
The locally generated initials placeholder only replaces Gravatar when the fallback is explicitly turned off; otherwise Gravatar remains the fallback.
Forgetting this also affects guest commenters
Since avatar resolution covers WP_Comment data too, a placeholder for an unregistered commenter is based on their email or name, not just registered users.
Local Avatar FAQ
These answers come directly from the verified class and its settings registration.
What does Local Avatar do?
It lets every logged-in user upload their own profile picture, stored on the site and shown automatically everywhere an avatar normally appears.
Can a role without media library access use this?
Yes. The upload field works for any logged-in user, including roles that can't otherwise upload to the media library.
Does this replace Gravatar automatically everywhere?
Yes. A single filter intercepts every existing avatar call, so nothing elsewhere needs to change.
What happens to users who haven't uploaded a picture?
They fall back to Gravatar by default, or to a locally generated initials placeholder if the Gravatar fallback has been disabled.
Does the initials placeholder make any external request?
No. It's generated inline as an SVG data URI, with no file and no network request involved.
Can I switch back to a previously uploaded picture?
Yes. Up to 8 previous uploads stay selectable from a history gallery on the profile screen.
What happens when I remove my current avatar?
Only the active pointer gets cleared; the picture itself stays in the history gallery in case it's wanted again later.
Is an uploaded file actually verified as a real image?
Yes. Beyond the file type check, the upload is independently confirmed to be a genuinely readable image before it's stored.
Can I delete a picture that belongs to another user?
No. Ownership gets verified before any selection or deletion, so only a user's own uploads can be managed this way.
Who can enable this module and its Gravatar setting?
Only an administrator with access to the TheOneWP settings screen.
Stop sending user emails to a third party for a picture.Store avatars locally, for every role.
Use Local Avatar to let every user upload a real profile picture, replacing Gravatar automatically everywhere, with the option to eliminate outbound requests entirely.

