Recently I had to add imgproxy to a section of a Laravel which hosts CMS content through a WYSIWYG and is persisted as html.
I decided to use a middleware to rewrite the content, I used the following (well rated) packages to help:
imgproxy
For local development, I obviously use docker.
The following variables will need to be added to .env file for your Laravel project (and they are the same that we will pass to our imgproxy service later):
IMGPROXY_KEY=
IMGPROXY_SALT=
IMGPROXY_SIGNATURE_SIZE=32
For IMGPROXY_KEY and IMGPROXY_SALT I use the following to generate values:
echo $(xxd -g 2 -l 64 -p /dev/random | tr -d '\n')
I don’t need to run it all the time, so this will suffice:
docker run --rm --env-file /path/to/laravel-site/.env -p 8888:8080 darthsim/imgproxy:latest
Since I use valet, I need to proxy since serving http content on https is tricky.
valet proxy --secure imgproxy.ac93 http://localhost:8888
This will mean that https://imgproxy.ac93.test will be what will used in the Laravel app to host our images through imgproxy. Add it to the .env.
IMGPROXY_URL=https://imgproxy.ac93.test
Add the following to a relevant config file, e.g. config/services.php:
<?php
return [
'imgproxy' => [
'url' => env('IMGPROXY_URL'),
'salt' => env('IMGPROXY_SALT'),
'key' => env('IMGPROXY_KEY'),
],
];
And finally, a little bit of dependency injection:
app/Providers/AppServiceProvider.php:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Imgproxy\UrlBuilder;
use Illuminate\Foundation\Application;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
$this->app->bind(UrlBuilder::class, function (Application $app) {
return new UrlBuilder(
config('services.imgproxy.url'),
config('services.imgproxy.key'),
config('services.imgproxy.salt')
);
});
}
}
Middleware
The middleware is relatively simple.
|
|
You can add ?no_imgproxy to url to skip the middleware for testing, etc.
|
|
Get the response content and load it into the DOM parser.
|
|
For each img in the DOM, don’t change svg and only rewrite images which are hosted on our site, i.e. in public; or hosted on our bucket.
imgproxy can be configured to host s3 content directly, but out of scope here, and serving public files is advantageous in this scenario.
|
|
Since this middleware is only applied to one section of the site which has a known max-width.
- Line 49: width - 896px, i.e. tailwind
max-w-4xl; we constrain all images to this width - Line 50: height - 0px, i.e. do not resize to a fixed height; aspect ratio will be respected
|
|
You can see the middleware gist.