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

Filament Svg Avatar Laravel Package

voltra/filament-svg-avatar

Replaces Filament's default avatar URL provider with inline SVGs, so default avatars load without external HTTP requests. Configurable size, background and text colors, font family, and per-plugin overrides via a publishable config file.

View on GitHub
Deep Wiki
Context7

Getting Started

What it does. Filament's default avatar provider points at an external service (ui-avatars.com) and returns a URL, so every user without an uploaded avatar costs you an outbound HTTP request and a third-party dependency. This package replaces that provider with one that builds an SVG from the user's initials and returns either a base64 data URI or raw inline <svg> markup. Nothing leaves your server.

Install and publish config.

composer require voltra/filament-svg-avatar
php artisan vendor:publish --tag="filament-svg-avatar-config"
php artisan vendor:publish --tag="filament-svg-avatar-views"   # optional, only if you want to restyle

First use case — the one-liner. If all you want is to stop the external requests, add a single line to your panel provider and you're done:

public function panel(Panel $panel): Panel
{
    return $panel
        ->defaultAvatarProvider(\Voltra\FilamentSvgAvatar\Filament\AvatarProviders\SvgAvatarsProviders::class);
}

Run one page with a nameless-avatar user and inspect the HTML: you should now see <img src="data:image/svg+xml;base64,…"> instead of a ui-avatars.com URL.

Where to look first, in order:

  1. config/filament-svg-avatar.php — six keys, all of them cosmetic (svgSize, backgroundColor, textColor, fontFamily, textDy, disallowPluginOverride). Read these before touching any code; they cover most asks.
  2. SvgAvatarsProviders vs RawSvgAvatarProvider — the choice between these two determines everything else in your setup.
  3. resources/views/vendor/filament/components/avatar.blade.php — the override hook if you go the raw-SVG route.
  4. SvgAvatarServiceContract — the seam to extend if you need initials or colors computed differently.

Implementation Patterns

Pattern 1 — provider swap (URL-based, zero view changes). Register SvgAvatarsProviders as above. Filament keeps rendering <img> tags, so column sizes, circular clipping, and alt attributes all keep working. Pick this when you want the change to be invisible to the rest of your UI.

Pattern 2 — plugin mode with per-panel branding. Useful in multi-panel apps where admin and customer panels share a codebase but not a palette:

->plugins([
    \Voltra\FilamentSvgAvatar\FilamentSvgAvatarPlugin::make()
        ->backgroundColor(\Spatie\Color\Hex::fromString('#3b5998'))
        ->textColor(\Spatie\Color\Hex::fromString('#e9ebee')),
])

The plugin auto-registers SvgAvatarsProviders for you, so there is no separate defaultAvatarProvider() call. Because the plugin is panel-scoped, this is the cleanest way to give each panel its own avatar colors without touching global config.

Pattern 3 — raw SVG + component override (the portable setup). This is the setup the README steers you toward for anything user-facing, and it's the one I'd default to. Two steps:

->defaultAvatarProvider(\Voltra\FilamentSvgAvatar\Filament\AvatarProviders\RawSvgAvatarProvider::class)
php artisan vendor:publish --tag=filament-svg-avatar-core-overrides

That publishes resources/views/vendor/filament/components/avatar.blade.php containing an <x-filament-svg-avatar::avatar-override> component. Filament now renders <svg> instead of <img>, which means the SVG inherits your panel's CSS font stack and renders crisply at any size without a raster decode step.

Pattern 4 — lock the brand. If you expose per-panel plugin configuration to other developers and want the palette to stay on-brand, set backgroundColor/textColor in config and set disallowPluginOverride => true. Config already wins over plugin and component values; this flag makes the intent explicit rather than accidental.

Pattern 5 — a custom service implementation. When the defaults don't fit — initials should come from a username instead of a name, or you want a deterministic color per user (hash the user ID into a fixed palette so each person keeps the same avatar color forever) — implement the contract and bind it:

class MySvgAvatarService extends \Voltra\FilamentSvgAvatar\Services\FilamentSvgAvatarService
{
    // override how initials / colors are derived
}

// in a service provider's register()
$this->app->scoped(
    \Voltra\FilamentSvgAvatar\Contracts\SvgAvatarServiceContract::class,
    MySvgAvatarService::class
);

Keep the binding scoped rather than singleton if your logic reads the authenticated user or request state.

Everyday integration notes. The package only ever supplies the default avatar; users with an uploaded avatar_url still short-circuit through Filament's own resolution, so you don't need to write that branching yourself. Table and infolist avatar components continue to work unchanged — ->circular(), ->size(), and column widths are all honoured because the override component accepts the same props Filament's expects. For your own test suite, assert on the rendered markup (assertSee('data:image/svg+xml') or assertSee('<svg', false)) rather than on network calls — that's the whole point of the swap.

Gotchas and Tips

Base64 SVGs cannot use webfonts. This is the biggest trap and the README says it plainly: SvgAvatarsProviders only renders correctly if the font is available on the user's machine, because the browser decodes the SVG as an isolated image where @font-face never loads. Your fontFamily config will silently fall back to a system font. If visual consistency matters — it usually does for a brand-facing panel — go with RawSvgAvatarProvider plus the component override. If you're on the base64 path, set fontFamily to something you know exists everywhere (ui-sans-serif, system-ui, sans-serif) instead of Filament's Inter.

Registration order in plugin mode. The plugin registers its provider, so anything you register that isn't a package provider must come after ->plugins([...]). The package's own providers (RawSvgAvatarProvider) are order-tolerant — v1.2.3 explicitly made the plugin skip overriding a provider that was already set — but external providers will be clobbered if you place them before the plugin. Symptom: your provider mysteriously never runs.

The core-overrides view is coupled to your Filament major version. Every upgrade from v3→v4→v5 requires re-publishing with --force, or you'll be running an override written against the old component's prop set. This is the single most likely source of "my avatars broke after composer update" tickets. Put a note in your upgrade checklist; ideally commit the published view so a diff shows up in review when Filament changes.

Don't blanket-spread $attributes in a hand-written override. Earlier versions leaked src and alt from the <img> contract into the <svg>, and translated strings from filament-panels::layout.avatar.alt were being harvested as the user's initials — you'd get a name starting with "A" for "Avatar". Fixed in 1.2.5–1.2.7 by dropping the alt prop entirely, but if you wrote your own override based on an old tutorial, you'll reintroduce it. Be aware that dropping alt means the avatar is now decorative to screen readers; if the avatar conveys information for you, wrap it in something with an accessible label rather than relying on the override.

Config silently wins over everything. backgroundColor, textColor, and fontFamily in config take precedence over plugin and component values. If your per-panel colors won't apply, the first thing to check is a non-null value in the published config file — not the plugin chain.

Watch payload size on large tables. A 500px base64 SVG is not tiny, and a table page rendering 50 of them inflates the HTML noticeably. If you see slow panel loads after switching, either drop svgSize or move to RawSvgAvatarProvider (inline markup is far more compact and compresses well over the wire).

textDy is a font-metric hack. The default .1em optically centres the initials for typical sans-serifs. Change fontFamily and you'll probably need to nudge textDy — the initials will look high or low in the circle but only at certain sizes, so check both sm and lg avatar sizes before shipping.

Vendor risk is real but bounded. Five stars, zero dependents, single maintainer — read the source before adopting. The upside is that the surface area is tiny (two providers, one service, one blade component), so forking or inlining it is a half-day job if it ever goes stale. Practically: keep your published avatar.blade.php under version control so reverting to stock Filament is a single git revert rather than an archaeology exercise.

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