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

Undraw Php Laravel Package

zpmlabs/undraw-php

Bring unDraw’s open-source SVG illustrations into PHP and Laravel projects with zpmlabs/undraw-php. Browse, fetch, and use customizable artwork to quickly add polished visuals to your app’s UI.

View on GitHub
Deep Wiki
Context7

Getting Started

What this package is. zpmlabs/undraw-php is a thin PHP client around the unDraw illustration library: you ask for an illustration by name, hand it a brand colour, and get SVG markup back (or a file on disk). It is framework-agnostic but ships Laravel-friendly conveniences, so in a Laravel app it slots in as a content dependency rather than an infrastructure one — it produces empty-state art, onboarding panels, 404 pages and email headers.

Minimal steps.

composer require zpmlabs/undraw-php
php artisan vendor:publish --tag=undraw-config   # if the config tag is offered

Set any required base URI / storage path in config/undraw.php (or .env), then verify connectivity with a one-off php artisan tinker call before wiring it into a view. Keep the version constraint tight ("zpmlabs/undraw-php": "^1.0") — this is a 1.0.x line, so patch releases are intended to be drop-in.

Where to look first. The README's usage block and the package's single facade/service class are the whole surface area. There is no deep object graph to learn: one fetch method, one colour argument, one output mode. Read the config file before the source — for a package this size, the config is the documentation.

First use case. The highest-value, lowest-risk first integration is a Blade partial for empty states:

{{-- resources/views/components/empty-state.blade.php --}}
<div class="text-center">
    {!! unserialize(...) !!} {{-- no: see Gotchas on raw output --}}
</div>

Prefer writing the SVG to storage/app/public/undraw/{name}-{colour}.svg at build/deploy time and referencing it with asset(), rather than emitting remote-fetched markup inline. If you do inline it, gate the output behind a sanitised path.

Implementation Patterns

Resolve once, cache aggressively. The single most important pattern: never let an unDraw fetch happen inside a web request that a user is waiting on. unDraw is a third-party host; treat it like any other external API. Wrap the client in a small repository of your own:

final class IllustrationRepository
{
    public function __construct(private Undraw $client) {}

    public function svg(string $name, string $colour = '#6C63FF'): string
    {
        return Cache::rememberForever(
            "undraw:{$name}:{$colour}",
            fn () => $this->client->get($name, $colour)
        );
    }
}

Bind this in a service provider and only ever inject the repository, never the vendor client directly. That keeps a future v2 API change to one file.

Prefetch at deploy time. Add an Artisan command (or a post-autoload-dump/deploy hook) that iterates a hardcoded list of illustration names your UI references and warms the cache / writes to the public disk. This converts a runtime network dependency into a build artefact — the single biggest reliability win available with this package.

Theme with tokens, not literals. unDraw SVGs use one primary accent colour, which the package substitutes. Drive that from your design system so light/dark or per-tenant branding works:

$colour = config('brand.illustration_colour'); // or $tenant->accent_hex

Persist one cached variant per colour; do not attempt string surgery on the returned SVG yourself.

Blade integration. Expose it as an anonymous component (<x-illustration name="empty" />) that reads from the repository. Components keep the vendor call out of views and make it trivial to swap to a local asset later.

Use it off the request path where it shines. Mailables, PDF invoices, and generated OG images are ideal: rendering happens in a queue worker, so a slow fetch is a latency problem for a job, not a user. Combine with Storage::disk('public')->put(...) and reference by URL.

Testing. Register a fake in the container in TestCase::setUp returning a fixed <svg> fixture. Assert against your component's output, never the vendor client — that keeps the suite offline and immune to patch-level changes.

On v1.0.3 specifically. The release is a patch bump with no changelog detail beyond the compare link. Nothing here suggests a breaking change or a new feature to adopt. Upgrade within your existing ^1.0 constraint, run the suite, and move on — but do skim the diff for the vendor class's method signatures and the config file, since patch releases on a 1.0.x line occasionally slip in config key renames that a strict config cache won't catch until deploy.

Gotchas and Tips

Raw SVG output is an injection vector. {!! $svg !!} on third-party-fetched markup is an XSS path if the upstream response is ever compromised or MITM'd. Mitigations, in order of preference: (1) serve the SVG as a file from your own disk and use <img src>, which neutralises scripting; (2) sanitise with a whitelist library before inlining; (3) at minimum, assert the response starts with <svg and reject anything containing <script. Do not skip all three.

Illustration names are not stable identifiers. unDraw retires and renames artwork. A name that resolves today can 404 in six months, and the client will likely surface that as an exception or an empty string depending on config. Freeze the set you use in a config array or enum, and have the fetch path fail gracefully (fall back to a local static asset) so a renamed illustration doesn't take down a page.

Colour substitution is narrow. The package swaps the designated primary hex only — secondary tones, skin tones and the background stay fixed. Hex matching may be case-sensitive and may or may not accept shorthand or rgb(). Always pass a full uppercase #RRGGBB and eyeball the result once per illustration; some artwork hardcodes near-duplicate shades that won't be replaced.

Watch for silent network calls. A facade that resolves lazily is easy to trigger from a view composer, an accessor, or a Blade directive without realising it. Grep for the facade alias before shipping and confirm no fetch can occur during a normal page render — the failure mode is a page that hangs for the HTTP timeout whenever unDraw is slow.

Config cache and .env. If the package reads config at construction, php artisan config:cache in your deploy pipeline is mandatory, and any env-driven key must be present at build time. A missing key that defaults silently to a remote URL is the classic "works locally, times out in production" bug.

Licensing and attribution. unDraw artwork is permissively licensed (attribution appreciated, not required) but the license covers the illustrations, not the package's own code. Check the package's own LICENSE separately, and add a line to your third-party notices file so legal review doesn't surface it later.

Extension points are thin. For a package this small, the honest answer is: don't extend, wrap. Your own repository class plus a container binding gives you caching, fallbacks, logging and sanitisation — all things you'd otherwise be patching into vendor code. If you find yourself wanting a custom transport or a different CDN, that's the signal to fork the ~200 lines rather than fight the abstraction.

Debugging checklist when an illustration doesn't render: (1) does the name resolve with a bare client call in tinker? (2) is the response non-empty and starting with <svg? (3) is the cache key correct and is a negative result being cached? (4) is the hex actually present in the source SVG? (5) if serving from disk, are storage:link and file permissions right? In that order — it's almost always (1) or (3).

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core