Skip to content

Image Uploads & Variants

Uploads

Built-in sections that accept images (Hero bg_image, Features icons, etc.) write to the public disk under filamentcraft/uploads/ by default, with a maximum upload size of 20480 KB. Override with environment variables:

dotenv
FILAMENTCRAFT_UPLOADS_DISK=s3
FILAMENTCRAFT_UPLOADS_DIR=tenants/acme/site
FILAMENTCRAFT_UPLOADS_VISIBILITY=public
FILAMENTCRAFT_UPLOADS_MAX_KB=30720   # raise the 20480 KB default

The disk MUST be publicly readable so the renderer's Storage::disk()->url($path) call resolves to a working URL.

ImageValue

Image settings resolve to an ImageValue with public readonly properties: path, url, and (when known) width, height, alt, and disk. It's Stringable — echoing it in Blade outputs the url:

blade
<img src="{{ $section->settings->get('bg_image') }}"
     srcset="{{ $section->settings->get('bg_image')->srcset() }}"
     alt="{{ $section->settings->get('bg_image')->alt }}">

srcset() returns a medium 1x, large 2x pair built from the size variants below.

Size variants

ImageValue::small(), medium(), and large() return the original URL by default — FilamentCraft does not bundle an image transformer. To wire up your stack's resizer (Glide, Imgix, Cloudinary, etc.), register a resolver on the plugin:

php
->imageSizesUsing(fn (ImageValue $image, string $size): string => match ($size) {
    'small' => $glide->getUrl($image->path, ['w' => 480]),
    'medium' => $glide->getUrl($image->path, ['w' => 1024]),
    'large' => $glide->getUrl($image->path, ['w' => 1920]),
    default => $image->url,
})

imageSizesUsing() sets a static resolver at panel-definition time — every ImageValue in the app resolves its variants through it from then on.