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

Statamic Imagekit Laravel Package

aerni/statamic-imagekit

A Statamic addon that adds a simple image toolkit to your Antlers templates, letting you generate resized, cropped, and optimized image URLs with clean tag syntax instead of wrestling with Glide parameters by hand. Handy for responsive images and srcsets.

View on GitHub
Deep Wiki
Context7

Getting Started

The package wraps ImageKit's URL-based transformation and upload APIs behind a Laravel facade, config file, and (usually) a storage disk driver. First steps:

composer require imagekit/imagekit-laravel
php artisan vendor:publish --tag=imagekit-config

Populate .env with the three values you'll find in the ImageKit dashboard under Developer Options → API Keys:

IMAGEKIT_PUBLIC_KEY=public_xxx
IMAGEKIT_PRIVATE_KEY=private_xxx
IMAGEKIT_URL_ENDPOINT=https://ik.imagekit.io/your_id

Then use the facade to render a transformed URL in a Blade view:

<img src="{{ ImageKit::getUrl('products/chair.jpg', ['width' => 400, 'height' => 400, 'crop' => 'at_max']) }}"
     alt="Chair">

Where to look first:

  • config/imagekit.php — endpoint, keys, and (in v2.2.0) the new bypass toggle.
  • The ImageKit facade's getUrl() / upload() methods — this is 90% of daily use.
  • The package's storage disk driver (imagekit) if you want Storage::disk('imagekit')->put(...) to upload natively.

The most common first use case is not uploading at all — it's rewriting existing image paths into ImageKit URLs so you get resizing, format negotiation (AVIF/WebP), and CDN delivery for free.

Implementation Patterns

URL generation everywhere, uploads where needed. Treat getUrl() as a pure string transform — call it in Blade, in API resources, in model accessors. It does no network I/O, so it's cheap and safe to call liberally.

// app/Models/Product.php
public function getThumbnailAttribute(): string
{
    return ImageKit::getUrl($this->image_path, [
        'width' => 300, 'height' => 300, 'crop' => 'at_max', 'format' => 'auto',
    ]);
}

Centralize transformation presets. Don't scatter magic arrays. A small config array or an enum keeps responsive variants consistent:

// config/imagekit.php (your additions)
'presets' => [
    'thumb'  => ['width' => 200, 'height' => 200, 'crop' => 'at_max', 'format' => 'auto'],
    'hero'   => ['width' => 1600, 'format' => 'auto', 'quality' => 80],
],

Upload from a controller or job. Uploads are synchronous HTTP calls to ImageKit — push them into a queued job for large files or bulk imports so you don't block the request:

$result = ImageKit::upload($request->file('photo'), [
    'fileName' => Str::uuid() . '.jpg',
    'folder'   => '/products',
]);
$product->update(['image_path' => $result->filePath]);

Store the filePath, not the full URL. Persist /products/abc.jpg. The full URL is derived at render time, so if you ever change endpoints, add a CDN alias, or enable the new bypass mode for local dev, no data migration is needed.

Local development bypass (v2.2.0). The headline feature of this release: you can now serve images from your normal local/storage path instead of hitting ImageKit. This closes the long-standing pain of "my images 404 locally because the endpoint points at a remote ImageKit instance." Intended workflow:

# local only
IMAGEKIT_BYPASS=true

(or the equivalent config key — confirm the exact name in config/imagekit.php after publishing). When enabled, getUrl() should return your asset/storage path unchanged, so the same Blade templates render working images against public/ or a local public disk without code changes. Leave it false in staging/production. Do not commit IMAGEKIT_BYPASS=true to a shared .env — scope it to .env / .env.local and keep it out of .env.example.

Integration tips.

  • If you use Laravel's filesystem, configure an imagekit disk and use Storage::disk('imagekit') so uploads go through the same code path as S3/local.
  • For signed URLs (private assets), generate them server-side only; never let the private key reach the browser.
  • Use format => 'auto' rather than hardcoding webp — ImageKit negotiates per Accept header and will serve AVIF where supported.

Gotchas and Tips

Config caching silently wins. php artisan config:cache freezes config/imagekit.php at build time. If you flip IMAGEKIT_BYPASS (or rotate keys) in .env, run php artisan config:clear or the change won't take effect. This bites people most in Docker/CI where the cache is built during the image.

The bypass toggle is a local-dev tool, not a feature flag. Because it changes the shape of the URL returned, any code that does string surgery on the result (parsing the ImageKit host, appending ?tr= params, checking str_starts_with($url, 'https://ik.imagekit.io')) will behave differently when it's on. Audit those call sites, or better, avoid parsing URLs — keep the path authoritative.

Missing transformations produce a valid-but-untransformed URL, not an error. A typo like widht won't throw; you'll just get the original image at full size, which is easy to miss until a Lighthouse run. Double-check transformation key spelling and watch your page weight.

Paths are relative to your endpoint. ImageKit::getUrl('/products/a.jpg') and 'products/a.jpg' may resolve differently depending on the package version's normalization. Pick one convention (leading slash) and be consistent; double slashes in the endpoint + path silently break transforms.

Upload errors are runtime exceptions. ImageKit returns 4xx bodies for bad file names (spaces, unsupported types) and auth failures. Wrap uploads in try/catch and log the response — the exception message alone often omits the useful detail.

Test doubles. The facade is easy to fake in feature tests (ImageKit::shouldReceive('getUrl')->andReturn(...)), but prefer asserting on the stored filePath and letting getUrl() run for real in integration tests — it's a deterministic string builder and doesn't need mocking. If the bypass option exposes a helper to resolve the "effective" path, use it in tests to assert both modes.

Extension points to know before you need them. If the package binds a singleton for its client, you can swap or decorate it in a service provider for retries, logging, or a custom HTTP client (timeouts, withOptions). Check the ImageKitServiceProvider — that's the seam for injecting middleware rather than forking the package. When a future release adds features like this bypass flag, that binding is also where behavior is most likely to change, so read the provider diff on upgrade.

Upgrade note. v2.2.0 is additive — no breaking changes — but re-publish and diff config/imagekit.php, since the bypass option likely ships as a new config key defaulting to false. Merge the new key into your existing config rather than overwriting your customizations.

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.
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr
laravel2580/idehelpers
delatbabel/viewpages
anavel/gettext
muhamadrezaar/highcharts
delatbabel/keylists
frankkessler/salesforce-laravel-oauth2-rest
anavel/foundation
wdmtech/enviricons
eii/laravel-captcha
muka/shape-reader
tdt/json