hosmelq / laravel-imgproxy
Build imgproxy URLs in Laravel with optional encryption and signing.
Requires
- php: ^8.4
- hosmelq/imgproxy: ^2.0
- illuminate/filesystem: ^12.0 || ^13.0
- illuminate/support: ^12.0 || ^13.0
- spatie/laravel-package-tools: ^1.93
Requires (Dev)
- ergebnis/composer-normalize: ^2.54
- hosmelq/php-coding-standard: ^1.1
- larastan/larastan: ^3.13
- laravel/pao: ^1.1
- orchestra/testbench: ^10.9 || ^11.3
- pestphp/pest: ^5.3
- pestphp/pest-plugin-rector: ^5.0
- shipmonk/composer-dependency-analyser: ^1.8
- thecodingmachine/safe: ^3.4
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Build imgproxy URLs in Laravel with optional encryption and signing.
Requirements
- ext-openssl
- Laravel 12+
- PHP 8.4+
Installation
Install Laravel imgproxy with Composer:
composer require hosmelq/laravel-imgproxy
Set IMGPROXY_BASE_URL to the root URL of the imgproxy server. Set
IMGPROXY_KEY and IMGPROXY_SALT to the hex-encoded key and salt the server
uses to check signatures.
Without a key and salt, URLs are built with insecure in place of a signature.
Sources are Base64-encoded by default. Signing and Base64 sources work with any
imgproxy server.
Build URLs
Start a builder with the Imgproxy facade, add processing options, and pass the
source URL to build():
use HosmelQ\Imgproxy\Laravel\Facades\Imgproxy; use HosmelQ\Imgproxy\ResizingType; $url = Imgproxy::builder() ->resize(ResizingType::Fill, 300, 300) ->quality(80) ->build('https://example.com/avatar.jpg');
The imgproxy() helper returns the same builder:
use HosmelQ\Imgproxy\ResizingType; use function HosmelQ\Imgproxy\Laravel\imgproxy; $url = imgproxy() ->resize(ResizingType::Fit, 1200) ->build('https://example.com/header.jpg');
Each call starts a fresh builder from the package configuration. Options appear in the URL in the order they are added. See hosmelq/imgproxy for every processing option.
format() sets the output format option without changing the URL's extension.
Pass an extension to build() to append one:
$url = Imgproxy::builder() ->format('webp') ->build('https://example.com/photo.jpg', 'webp');
Build URLs from disks
Call imgproxy() on a filesystem disk to use a file's URL as the source:
use HosmelQ\Imgproxy\ResizingType; use Illuminate\Support\Facades\Storage; $url = Storage::disk('public') ->imgproxy('images/header.jpg') ->resize(ResizingType::Fit, 1200) ->build('webp');
Builder options chain directly from the disk. build() takes no source URL, so
its first argument is the output extension.
Use temporary() when the source should be a temporary URL from the disk:
$url = Storage::disk('s3') ->imgproxy('private/report.png') ->temporary(now()->addMinutes(10)) ->build();
temporary() also accepts the disk's temporary URL options as its second
argument. The expiration applies to the source URL only. Add expires() with a
Unix timestamp when the imgproxy URL should expire too.
Read image information
Image-info URLs require imgproxy Pro. Start one with Imgproxy::infoBuilder(),
or with imgproxyInfo() on a disk:
use HosmelQ\Imgproxy\Laravel\Facades\Imgproxy; use Illuminate\Support\Facades\Storage; $url = Imgproxy::infoBuilder() ->dimensions() ->size() ->build('https://example.com/photo.jpg'); $url = Storage::disk('public') ->imgproxyInfo('photo.jpg') ->dimensions() ->build();
Image-info URLs are signed and encoded the same way as processing URLs. They do not accept an output extension.
Encrypt source URLs
Source encryption requires imgproxy Pro. Set IMGPROXY_SOURCE_ENCODING to
encrypted and IMGPROXY_ENCRYPTION_KEY to the hex-encoded key the server
uses. The key must decode to 16, 24, or 32 bytes.
By default, the IV is derived from the source URL and the key, so the same source always produces the same URL.
Call Imgproxy::buildIvUsing() from a service provider to generate the IV with
a custom callback:
use HosmelQ\Imgproxy\Laravel\Facades\Imgproxy; Imgproxy::buildIvUsing(function (string $sourceUrl): string { $hash = hash_hmac('sha256', $sourceUrl, config()->string('app.key'), true); return substr($hash, 0, 16); });
The callback receives the source URL, must return exactly 16 bytes, and applies
to processing and image-info URLs. Pass null to restore the default. Keep the
IV deterministic: a random IV produces a different URL on every build, which
defeats caching. The example derives the IV from APP_KEY, so rotating that key
changes every encrypted URL it generates.
Configuration
Publish the configuration file:
php artisan vendor:publish --tag=imgproxy-config
The configuration file also covers the arguments
separator, signature size, short option names, presets-only mode, option
aliases, source chunking, source filenames, and trusted signatures, each with
its environment variable where one exists. Image-info URLs use
info_only_presets and info_option_aliases in place of only_presets and
option_aliases, and share every other setting.
Creating a builder throws an InvalidArgumentException when the base URL is
missing, the source encoding is unknown, encrypted sources have no encryption
key, or an option alias names an unknown option.
Use dependency injection
Inject ImgproxyManager when a class should not depend on the facade:
use HosmelQ\Imgproxy\Laravel\ImgproxyManager; use HosmelQ\Imgproxy\ResizingType; final class AvatarUrl { public function __construct(private ImgproxyManager $imgproxy) {} public function handle(string $source): string { return $this->imgproxy->builder() ->resize(ResizingType::Fill, 300, 300) ->build($source); } }
Deploy imgproxy
Deploy a ready-to-run imgproxy server with the Railway template:
Development
Run the test suite with:
composer test
Changelog
See CHANGELOG.md for a list of changes.
Contributing
Pull requests are welcome. Please run the test suite before submitting changes.
License
The MIT License (MIT). Please see License File for more information.