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

Imgproxy Php Laravel Package

onliner/imgproxy-php

PHP client for imgproxy that builds signed and unsigned image URLs through a fluent, chainable API. Supports resizing, cropping, gravity, format conversion, and Laravel integration, letting you serve optimized, secure images from your own imgproxy instance.

Deep Wiki
Context7

Getting Started

Three things must exist before the package is useful: a running imgproxy instance, a hex-encoded IMGPROXY_KEY, and a hex-encoded IMGPROXY_SALT. The library only builds and signs URLs — it never talks to the imgproxy server itself.

composer require onliner/imgproxy-php

Add credentials to config/services.php:

'imgproxy' => [
    'url'  => env('IMGPROXY_URL', 'http://imgproxy:8080'),
    'key'  => env('IMGPROXY_KEY'),
    'salt' => env('IMGPROXY_SALT'),
],

First use case — a signed thumbnail URL:

use Onliner\ImgProxy\ImgProxy;

$client = new ImgProxy(
    config('services.imgproxy.url'),
    config('services.imgproxy.key'),
    config('services.imgproxy.salt'),
);

$url = $client->url('https://cdn.example.com/products/42.jpg')
    ->width(800)
    ->height(600)
    ->fit('cover')
    ->format('webp')
    ->quality(80)
    ->build();

Where to look first:

  1. The README for the supported processing-option methods (resize/fit, gravity, format, quality, DPR, blur, watermark, etc.).
  2. src/ for the ImgProxy entry class and the option/URL builder — the fluent methods map almost 1:1 to imgproxy processing options, so the imgproxy docs are your second reference.
  3. The signing implementation, to confirm it uses HMAC-SHA256 over the encoded path with key/salt as raw bytes (not the hex strings).

If you only ever need one size, stop here. The rest of this assessment is about keeping signed URLs maintainable once they spread across views, jobs, and API resources.

Implementation Patterns

Bind a singleton and inject it. Don't new ImgProxy(...) in controllers. Register it once so config changes and testing stay in one place:

// AppServiceProvider::register()
$this->app->singleton(ImgProxy::class, fn () => new ImgProxy(
    config('services.imgproxy.url'),
    config('services.imgproxy.key'),
    config('services.imgproxy.salt'),
));

Centralize transformation presets. Scattering ->width(300)->format('webp') across Blade templates guarantees inconsistent cache keys and drift. Define named presets in config or an enum:

// config/images.php
'presets' => [
    'thumb'    => ['width' => 200, 'height' => 200, 'fit' => 'cover'],
    'product'  => ['width' => 1200, 'height' => 900, 'fit' => 'cover', 'format' => 'webp'],
    'hero'     => ['width' => 1920, 'fit' => 'cover', 'dpr' => 2],
],

Then a small application-level factory applies them, so presets stay the source of truth even if the package API changes.

Responsive srcset is the highest-leverage pattern. The library is just URL construction, so loop widths and emit a set:

$srcset = collect([320, 640, 1280, 1920])
    ->map(fn ($w) => $client->url($source)->width($w)->fit('cover')->format('webp')->build()." {$w}w")
    ->implode(', ');

Sign remote sources, not just local paths. Imgproxy accepts full upstream URLs, S3 references (s3://bucket/key), and local paths depending on how the server is configured. The package's "flexible path generation" is where this matters — pass the source exactly as imgproxy expects it, then let the library handle signing. For private buckets, prefer imgproxy-native source options (S3 auth via server-side config) over pre-signed upstream URLs, which expire and poison your CDN cache.

Blade directives / model accessors. Wrap the builder in a helper so views stay readable:

@imgproxy($product->image, 'product', ['alt' => $product->name])

For Eloquent, an imageUrl(string $preset) accessor keeps transformation logic off the model's public surface while still caching the built URL.

Job and API usage. Signed URLs are deterministic, so they are safe to generate in queued jobs and API resources. If the same URL is generated repeatedly, memoize per request; if you use signed URLs in emails or webhooks, generate them close to send time — they're cheap, but base URLs and credentials can rotate.

Testing. Assert against a fixed key/salt and snapshot the URL. Because signing is deterministic, a hash comparison catches accidental option reordering or encoding changes:

$this->assertSame($expected, $client->url($src)->width(300)->build());

Gotchas and Tips

  • Hex vs. raw key/salt. Imgproxy generates IMGPROXY_KEY/IMGPROXY_SALT as hex strings. The signer needs raw bytes. If signatures fail with a 403, this is almost always why — confirm whether the package decodes hex internally or expects raw values, and don't paste the hex string straight in if it expects hex2bin().
  • Signatures cover the full path, including option order. w:300/h:200 and h:200/w:300 produce different signatures and different CDN cache entries. Pick a canonical option order (a preset array, sorted) and stick to it, or you'll silently fragment your cache.
  • Trailing slashes and double-encoding. A base URL with a trailing slash plus a leading slash on the path yields //. Likewise, encoding an already-encoded source URL double-encodes it. Normalize base URL with rtrim($url, '/') and let the builder encode the source once.
  • unsafe mode is dev-only. If the package exposes an unsigned/unsafe builder, gate it behind app()->isLocal(). Shipping it to production lets anyone generate arbitrary transformations and hotlink your origin storage.
  • Changing any option invalidates the signature. This is expected, but it means a signed URL sent in a transactional email breaks the moment you edit the preset. For long-lived links, pin the preset in config rather than editing inline calls.
  • DPR and floating-point sizes. Passing dpr=2 multiplies output dimensions server-side; if your CDN or layout assumes the requested width, images will be 2× larger than expected. Keep DPR out of presets used for fixed-size elements.
  • Format fallback. Requesting webp/avif without Accept-based fallback leaves older clients with a broken image. Either generate a second signed URL in the fallback format or rely on imgproxy's auto-format (format: auto) if your server build supports it.
  • Cache invalidation. The URL is the cache key. There is no purge API in this package — if a source image changes in place, you must change something in the URL (a version query, filename hash) or purge your CDN separately.
  • Debugging a 403. Verify (1) key/salt bytes, (2) that the signed string is the exact path you requested, (3) that your proxy in front of imgproxy isn't rewriting the path before signature validation. Log the unsigned path alongside the built URL — that's the only thing the signer actually sees.
  • Extension points. The package's value is the fluent builder; where it lacks an option, most imgproxy features are still reachable by appending the raw query/option fragment before ->build(), or by composing the path yourself and using only the signing helper. Prefer that over forking — forking a 25-star package is a maintenance liability versus a thin wrapper.
  • Pin the version. The last release is dated 2026-04-01; keep a ^ constraint in composer.json and run the test snapshot after upgrades, since option names and the signer are the surfaces most likely to shift.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource