astrotomic/laravel-imgix
Laravel package that generates Imgix URLs for your images, letting you apply Imgix transformation parameters like resizing, cropping, and format conversion directly from PHP. Integrates with Eloquent models and Blade to simplify responsive image handling.
composer require astrotomic/laravel-imgix — 1.3.0 adds Laravel 12 support, so the constraint no longer blocks an upgrade. The package is a thin wrapper around imgix's PHP URL builder: it does no HTTP calls, it only assembles URLs.Imgix facade are registered automatically on Laravel 8+. If you use a config/app.php providers/aliases array, register them there.php artisan vendor:publish --provider="Astrotomic\Imgix\ImgixServiceProvider"
IMGIX_SOURCE=your-source.imgix.net
IMGIX_SIGN_KEY= # only if your source requires signed URLs
IMGIX_USE_HTTPS=true
use Astrotomic\Imgix\Facades\Imgix;
Imgix::create('products/thumb.jpg'); // https://your-source.imgix.net/products/thumb.jpg
config/imgix.php (source, sign key, https toggle) → the facade's create() signature → the README's parameter examples. The facade returns a fluent builder, so ->with*() methods are where the day-to-day value lives.Keep the source/path decision in one place. Don't sprinkle Imgix::create('...') with hardcoded paths across views. Put a cover_url accessor (or a small ImageUrl service) on your model that maps a stored disk path to the imgix path, so a future source or bucket change is one edit.
Render responsive images via a Blade component. Wrap srcset generation once and reuse it:
<x-imgix-image path="hero.jpg" :widths="[400, 800, 1200, 1600]" alt="Hero" />
Inside the component, loop the widths, call the builder per width, and emit srcset + a fallback src (the largest or a sizes-matched default). This keeps parameter drift out of templates.
Treat parameter sets as named presets. Most teams use the same 3–5 transforms (card thumb, hero, avatar). Define them as arrays/constants and map them to builder calls, rather than chaining ad-hoc params in Blade. It makes cache keys stable and review diffs readable.
Sign only when you must. If IMGIX_SOURCE is public, leave sign_key empty — signed URLs can't be hand-edited and add complexity to local debugging. Enable signing per-environment (production source signed, local source public) rather than globally.
Generate URLs at render time, not at write time. Unless you have a hard caching requirement, don't persist generated URLs in the database; a later fit/auto policy change would require a backfill. Persist the path, compose the URL in the accessor.
Testing is string assertion, not faking. There's no HTTP client involved, so Http::fake() does nothing. Assert the built URL contains the expected host, path, and query params, and point the config at a fake source in phpunit.xml:
$this->assertStringContainsString('w=800', $model->cover_url);
Integration point for existing <img> markup: use it as a pure URL source for src/srcset and let the browser do the work — do not pair it with intervention/image for resizing, that duplicates what imgix already does at the edge.
str_replace params, append &foo=bar, or reorder args on a signed URL — rebuild it through the builder instead. A "signature mismatch" 403 almost always means post-hoc URL editing or a sign_key that doesn't match the source's key.config:cache traps. The config reads env() at boot; after changing IMGIX_SOURCE in .env locally you must php artisan config:clear. This is the #1 "it works in tinker but not in the app" cause.'/hero.jpg' can produce a double slash and a broken/uncached asset. URL-encode filenames containing spaces, #, ?, or unicode; those characters silently truncate the path otherwise.w, h, fit, auto). Fluent builder methods map to these; if you pass a raw params array, use the imgix names, not the method names. Ordering doesn't matter for correctness but does matter for CDN cache keys — keep presets deterministic (same params, same order) or you'll fragment the cache.IMGIX_USE_HTTPS=false will produce http:// URLs and mixed-content warnings on HTTPS pages. Leave it true and only flip it for a legacy source.asset() paths — the container binding and facade are the intended extension point.config/imgix.php hasn't gained new keys by re-publishing to a temp path and diffing, rather than overwriting your live config.How can I help you explore Laravel packages today?