Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Gravatar Laravel Package

forxer/gravatar

forxer/gravatar is a lightweight PHP library for generating Gravatar avatar URLs and retrieving public profile data. It supports configurable sizes, default images, ratings, and hashes, with optional Laravel integration for quick use in Blade views and applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install with Composer:

composer require forxer/gravatar

This is v7.0.0 — it requires PHP 8.4 (typed class constants, asymmetric visibility and property hooks are used). Confirm your composer.json platform constraint allows 8.4 before upgrading.

The entry point is the Forxer\Gravatar\Gravatar facade-style class with two factory methods:

  • Gravatar::image(string $email) → returns an Image object
  • Gravatar::profile(string $email) → returns a Profile object

Both implement the new GravatarInterface (url(), copy() and Stringable), so you can type-hint against it.

Smallest first use case — drop an avatar into a Blade view:

<img
    src="{{ Gravatar::image(auth()->user()->email)->size(80)->url() }}"
    alt="Avatar"
    width="80"
    height="80"
>

Image is Stringable, so echo Gravatar::image($email) works too — but prefer ->url() in attributes for clarity. Look first at Gravatar, Image and Profile; those are the entire public surface you'll touch day to day.

Implementation Patterns

Fluent avatar builder. Image is immutable (each call returns a copy()), so you can safely reuse a base image in config or a service provider:

use Forxer\Gravatar\Gravatar;

$avatar = Gravatar::image($user->email)
    ->size(200)
    ->rating('pg')
    ->default('identicon');

echo $avatar->url();

Building a Gravatar value from the user model. Since email normalization (trim + lowercase) happens in the property hook, you can pass $user->email raw. This also means the SHA-256 hash is stable regardless of casing, which matters now that hashing changed from MD5 to SHA-256 — any hashes you cached elsewhere must be recomputed.

Fetching profile data (new in v7). The library no longer makes HTTP calls — Profile::getData() is gone. Use Profile::url() (which points at https://api.gravatar.com/v3/profiles/{sha256_hash}) with your own client. Laravel's Http facade is the natural choice:

use Illuminate\Support\Facades\Http;
use Forxer\Gravatar\Gravatar;

$profile = Gravatar::profile($user->email);

$response = Http::timeout(3)
    ->withHeaders(['Accept' => 'application/json'])
    ->get($profile->url())
    ->throw()
    ->json();

Wrap this in a dedicated service (e.g. GravatarProfileFetcher) so you can mock it in tests and add caching without touching call sites.

Cache aggressively. The v3 profile endpoint is remote and rate-limited. Cache per-user keyed on the SHA-256 hash, with a short TTL:

$hash = sha256(strtolower(trim($user->email))); // or reuse Gravatar internals

return Cache::remember("gravatar:profile:{$hash}", now()->addHours(6), function () use ($user) {
    return Http::get(Gravatar::profile($user->email)->url())->json();
});

Type-hint the interfaces. GravatarInterface covers both Image and Profile — useful in helper signatures. GravatarExceptionInterface is a marker implemented by all five exception classes, so a single catch block can handle any validation error (invalid size, invalid rating, etc.):

use Forxer\Gravatar\Exceptions\GravatarExceptionInterface;

try {
    $url = Gravatar::image($email)->size(1024)->url();
} catch (GravatarExceptionInterface $e) {
    report($e);
    $url = asset('img/default-avatar.png');
}

Blade component wrapper. Encapsulate size/rating defaults in a component so views stay declarative:

// app/View/Components/Avatar.php
public function render(): View
{
    return view('components.avatar', [
        'src' => $this->email
            ? Gravatar::image($this->email)->size($this->size)->url()
            : asset('img/default-avatar.png'),
    ]);
}

Setting values via methods (v7 change). email, initials, initialsName and forceDefault are private(set). Use the fluent methods:

Gravatar::image()->email($email)->initials('JD')->forceDefault(true);

Gotchas and Tips

  • Breaking — hashing is SHA-256 now. Any precomputed MD5 hashes in your DB, cache, queues or external systems will no longer correspond. Recompute them. Gravatar itself accepts both, so remote avatars still resolve; the break is on your side of the hash.
  • Breaking — Profile::getData() is gone. Do not upgrade if you were relying on it. The removal is a genuine security fix (CWE-502: file_get_contents() + unserialize() on remote data), so it's not coming back. Plan the migration before you bump the constraint.
  • Breaking — ProfileFormat enum, ProfileHasFormat trait, InvalidProfileFormatException are removed. Gravatar::profile() and Gravatar::profiles() no longer accept $format. The v3 API only returns JSON. Remove the argument and any format-related catch blocks.
  • Profile::url() is an API URL, not a public page. https://api.gravatar.com/v3/profiles/{hash} is meant to be consumed by an HTTP client. Don't embed it in <img> tags — use Gravatar::image() for that.
  • forceDefault() no longer accepts null. The signature went from ?bool to bool. If you had a config toggle passing null, resolve it to true/false at the call site.
  • Read-only properties throw on write. ->email = 'x' now raises an error rather than silently doing nothing. If you see Cannot modify readonly property, switch to ->email('x').
  • URL canonical change. Gravatar::URL is now 'https://gravatar.com/' (HTTPS, no // scheme-relative prefix). If you asserted on the old string in tests or used //www.gravatar.com in CSP allowlists, update both. HTTPS in the URL also means you no longer need mixed-content workarounds.
  • PHP 8.4 is a hard floor. The new const string and public private(set) syntax won't parse on earlier runtimes. Check your CI matrix and any pinned tooling (PHPStan, Pint, Rector) supports 8.4 — the package now ships config for all three.
  • Debugging missing avatars. Gravatar returns a 404 (or the default image) for unregistered emails. When ->default() isn't set, the rendered URL can look identical to a working one but resolve to the default. Set d=identicon (or similar) explicitly in dev so you can tell "no account" apart from "broken URL".
  • Extension points. Prefer composition (wrap Gravatar in your own service / facade) over subclassing. Image and Profile are immutable and copy-on-modify, so subclass constructors are fragile. If you need custom behaviour, implement a small adapter exposing your own avatarUrl(User $user): string method.
  • Testing. The GravatarInterface and the SHA-256 hashing make snapshot testing straightforward: assert on the final URL string. For profile fetching, use Http::fake() against Profile::url() — no package mocking needed since the library itself is now HTTP-free.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package