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

Multiavatar Php Laravel Package

multiavatar/multiavatar-php

Multiavatar PHP generates unique, deterministic SVG avatars from any string. It bundles the full Multiavatar SVG dataset and returns ready-to-use markup, with no API calls or image processing required, making it easy to add colorful user avatars to Laravel or plain PHP applications.

Deep Wiki
Context7

Getting Started

Install with Composer — the package is a plain library, so there is no service provider, no config file to publish, and nothing to register in config/app.php:

composer require multiavatar/multiavatar-php

The first place to look is the class itself (src/Multiavatar.php or src/Multiavatar/Multiavatar.php depending on the version). It contains one callable method, __invoke(string $seed): string, plus a set of large arrays of SVG path fragments (backgrounds, hair, eyes, mouth, clothing, etc.). That file is the whole package.

Minimal usage:

use Multiavatar\Multiavatar;

$svg = (new Multiavatar())('[email protected]');
// $svg is a complete <svg …>…</svg> string

The generator hashes the seed string, splits the hash into indices, and picks one fragment per feature group. Same seed always yields the same avatar, on any server, with no storage. That determinism is the entire value proposition.

First use case: a fallback avatar for users who haven't uploaded a profile picture. Drop it into an existing accessor or a Blade component and you're done — you don't need a database column, a filesystem, or a job.

// User model
public function getAvatarSvgAttribute(): string
{
    return (new Multiavatar())($this->email ?: (string) $this->id);
}

Implementation Patterns

Blade component (inline SVG). Inlining keeps the avatar styleable with CSS and avoids a second HTTP request:

// app/View/Components/Avatar.php
class Avatar extends Component
{
    public function __construct(public string $seed, public string $class = '') {}

    public function render()
    {
        return view('components.avatar', ['svg' => (new Multiavatar())($this->seed)]);
    }
}
{{-- resources/views/components/avatar.blade.php --}}
<div class="avatar {{ $class }}" aria-hidden="true">{!! $svg !!}</div>

Dedicated SVG route (better for caching and CDNs). Serve a real image URL so browsers, Cloudflare, and Laravel's response cache can do their job:

Route::get('/avatar/{seed}.svg', function (string $seed) {
    $svg = Cache::remember("avatar:v1:{$seed}", now()->addWeek(),
        fn () => (new Multiavatar())($seed));

    return response($svg, 200, [
        'Content-Type'  => 'image/svg+xml',
        'Cache-Control' => 'public, max-age=604800, immutable',
    ]);
})->where('seed', '[A-Za-z0-9._-]{1,64}');

Constrain the route parameter, as above — don't let arbitrary bytes become cache keys.

Data URIs for email and PDF. Email clients are hostile to SVG, and DOM PDF libraries often can't fetch routes. Embed instead:

$src = 'data:image/svg+xml;base64,' . base64_encode((new Multiavatar())($user->email));

<img src="{{ $src }}"> works in most modern email clients, though Outlook desktop will still refuse SVG — fall back to a PNG in that case.

Persist at registration if you need an immutable avatar. Generate once and store it, so a later seed change (email change, or a package upgrade that alters the palette) doesn't silently redraw everyone:

Storage::disk('public')->put("avatars/{$user->id}.svg", (new Multiavatar())($user->email));

Seeding. In factories and seeders, feed fake()->email() — you get a visually stable fixture set that looks realistic in screenshots and demos, with no external image service.

"Regenerate" affordance. Since the seed is the only input, salting it gives you a new avatar on demand: (new Multiavatar())($email . $nonce). Store the nonce, not the SVG, if you care about disk.

Gotchas and Tips

  • The seed is not normalized. "Alice", "alice ", and " alice" are three different avatars. Normalize once, before you call it: mb_strtolower(trim($seed)), and pick either email or ID consistently. Otherwise a user's avatar will flip when they edit their profile.
  • Multibyte and emoji seeds need checking. The hash walks the string; depending on the port, it may be byte-oriented, which is fine (still deterministic) but means mb_strtolower on a UTF-8 name may not collapse case the way you expect. For anything user-facing, hash a stable ASCII fallback (email or ID) rather than a display name.
  • Empty string is valid input and produces an avatar. Guard if (! $seed) at the call site if a blank avatar is not what you want.
  • Not unique, not secure. It's a hash-to-palette mapping, not a cryptographic identity. Collisions happen at scale and the output is reversible-ish by anyone with the package. It's a placeholder, not an identicon security feature.
  • Treat the palette as part of your UI contract. The SVG fragment arrays can change between versions, which silently redraws every avatar in your app. Pin the version in composer.json ("multiavatar/multiavatar-php": "1.*") and bump deliberately, then purge the avatar cache.
  • Cache-bust on upgrade. If you cache by avatar:{seed}, include a version token in the key (avatar:v2:{seed}) so a palette change isn't masked by stale cache entries.
  • Serving it as a response requires the right Content-Type. image/svg+xml, not text/html. For Content-Disposition: attachment downloads, use .svg and consider X-Content-Type-Options: nosniff.
  • Inline SVG is trusted; wrapper output is not. The generated markup is safe because it's package-authored. Anything you interpolate around it (aria-labels, titles, alt text) must be escaped with {{ }}. Never inline user-supplied SVG through the same {!! !!}.
  • Watch CSP. Inline <svg> is fine under img-src/style-src rules, but data: URIs need img-src data: in your policy. If you're on a strict CSP, the dedicated route pattern is the safer integration.
  • Output is a few KB and not gzipped by the package. Enable compression at the web-server or proxy layer; a page with 50 avatars is a real payload otherwise.
  • No extension points. There's no config, no theming hook — if you need brand colors or a monochrome variant, wrap it (post-process with a CSS filter, or fork the fragment arrays) rather than expecting a constructor option. The class is small enough that a subclass overriding the arrays is a legitimate approach.
  • Testing: assert determinism rather than the rendered output — $this->assertSame((new Multiavatar())('x'), (new Multiavatar())('x'));. Avoid snapshotting the full SVG unless you want a test failure on every package bump.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core