thomaswelton/laravel-gravatar
Laravel Gravatar generates Gravatar avatar URLs from user email addresses in Laravel apps. Configure image size, default fallback, rating, and secure URLs, then render avatars in Blade views or PHP via a convenient helper or facade. A lightweight way to add profile images without managing uploads.
composer require thomaswelton/laravel-gravatar
Thomaswelton\LaravelGravatar\LaravelGravatarServiceProvider and the Gravatar facade. On older apps, register manually in config/app.php:
'providers' => [Thomaswelton\LaravelGravatar\LaravelGravatarServiceProvider::class],
'aliases' => ['Gravatar' => Thomaswelton\LaravelGravatar\Facades\Gravatar::class],
php artisan vendor:publish --provider="Thomaswelton\LaravelGravatar\LaravelGravatarServiceProvider"
You should now have config/gravatar.php.resources/views/... and swap the <img src="..."> for the helper, then smoke-test in Tinker with Gravatar::src('[email protected]') to confirm you get a https://secure.gravatar.com/avatar/<md5>?... URL.The library is a thin URL builder around Gravatar's public API — the core surface is src($email), image($email, $alt, $attributes), and exists($email). Verify the exact signatures against the version you install before spreading them across the codebase.
Blade component (the 90% case). Wrap it once so views never call the facade directly:
{{-- resources/views/components/avatar.blade.php --}}
@props(['user', 'size' => 48])
<img src="{{ Gravatar::src($user->email) }}"
alt="{{ $user->name }}"
width="{{ $size }}" height="{{ $size }}"
class="rounded-full">
Model accessor. Centralize the email normalization and expose a stable attribute:
public function getAvatarUrlAttribute(): string
{
return Gravatar::src(strtolower(trim($this->email)));
}
Service wrapper for portability. Because the package is archived, hide it behind your own contract so swapping to creativeorange/gravatar or a raw URL builder is a one-file change:
interface AvatarProvider { public function url(string $email, int $size = 80): string; }
Bind the Gravatar implementation in a service provider; inject it into controllers and mailables rather than using the facade.
Config-driven defaults. Read env values into config/gravatar.php (GRAVATAR_SIZE, GRAVATAR_DEFAULT=identicon, GRAVATAR_RATING=g) so staging and production can differ without code changes. In mail templates and notifications, use src() (which returns an absolute URL) — relative URLs break in email clients.
Presence checks — cache aggressively. Gravatar::exists($email) performs a synchronous HTTP request. For a users index page, that's an N+1 over the network. Either cache the boolean (Cache::remember("gravatar:{$hash}", now()->addDay(), ...)) or skip exists() entirely and let Gravatar's d=404 return a 404, handling the fallback client-side with onerror.
Testing. Assert on the generated URL rather than hitting Gravatar: $this->assertStringContainsString(md5('[email protected]'), $user->avatar_url);. In feature tests, bind a fake AvatarProvider so no outbound calls occur.
illuminate/support constraint in its composer.json. On Laravel 9/10/11 you will likely need --with-all-dependencies or a fork; PHP 8.1+ may surface deprecation notices from untyped returns. If you want zero maintenance risk, replicate the feature with a five-line URL builder instead of adding the dependency.Gravatar is a common alias; if another package registers it, use the fully-qualified facade or alias it as GravatarHelper.g, pg, r, x; default accepts mp, identicon, monsterid, wavatar, retro, robohash, blank, or a URL-encoded image URL. Invalid values fall back silently, which makes bugs hard to spot.http://www.gravatar.com; on HTTPS apps this triggers browser mixed-content blocks. Set the secure config flag (or override the base URL) and confirm the output starts with https://.exists() is a network call. It's the single biggest performance trap in this package — never call it inside a loop or a Blade partial rendered per row. Cache results, or default to a local fallback image and skip the check.GRAVATAR_* env vars, run php artisan config:clear; otherwise you'll debug a config change that never took effect.How can I help you explore Laravel packages today?