PHPackages                             imsyuan/filament-image-caption-upload - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Image &amp; Media](/categories/media)
4. /
5. imsyuan/filament-image-caption-upload

ActiveLibrary[Image &amp; Media](/categories/media)

imsyuan/filament-image-caption-upload
=====================================

Filament v3 FileUpload component with per-image caption support

3.0.1(1mo ago)141MITBladePHP ^8.2CI passing

Since Jun 10Pushed 1mo agoCompare

[ Source](https://github.com/imsyuan/filament-image-caption-upload)[ Packagist](https://packagist.org/packages/imsyuan/filament-image-caption-upload)[ Docs](https://github.com/imsyuan/filament-image-caption-upload)[ RSS](/packages/imsyuan-filament-image-caption-upload/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (4)Dependencies (13)Versions (8)Used By (0)

Filament Image Caption Upload
=============================

[](#filament-image-caption-upload)

[![Latest Version on Packagist](https://camo.githubusercontent.com/36f5aefbd1e60a3a8418afd4e7148b00a987a139bcdc2942f7b70175ed8fc207/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f696d737975616e2f66696c616d656e742d696d6167652d63617074696f6e2d75706c6f61642e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/imsyuan/filament-image-caption-upload)[![GitHub Tests Action Status](https://camo.githubusercontent.com/4c24485fc2a15bab494ef8e8a633c4506d7e308aa63341838a66dcf3af7a52f7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f696d737975616e2f66696c616d656e742d696d6167652d63617074696f6e2d75706c6f61642f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/imsyuan/filament-image-caption-upload/actions?query=workflow%3Atests+branch%3Amain)[![PHPStan](https://camo.githubusercontent.com/daca159a161c9f06700f3c304e7c843372059f82516381aef18bc5e8309f3cb3/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f696d737975616e2f66696c616d656e742d696d6167652d63617074696f6e2d75706c6f61642f7068707374616e2e796d6c3f6272616e63683d6d61696e266c6162656c3d7068707374616e267374796c653d666c61742d737175617265)](https://github.com/imsyuan/filament-image-caption-upload/actions?query=workflow%3Aphpstan+branch%3Amain)[![License](https://camo.githubusercontent.com/8162f4ae5b2f816252f67896dec74ff88da75c5b0d708056419bca6258dd0b03/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f696d737975616e2f66696c616d656e742d696d6167652d63617074696f6e2d75706c6f61642e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/imsyuan/filament-image-caption-upload)

**English** | [繁體中文](README.zh-TW.md)

A [Filament v3](https://filamentphp.com) form component that extends the built-in `FileUpload` to attach a per-image caption beneath each uploaded file — with no build step required.

[![Demo](https://raw.githubusercontent.com/imsyuan/filament-image-caption-upload/main/art/demo.png)](https://raw.githubusercontent.com/imsyuan/filament-image-caption-upload/main/art/demo.png)

---

Features
--------

[](#features)

- **Drop-in replacement** — extends Filament's native `FileUpload`, so every existing option (`->image()`, `->multiple()`, `->reorderable()`, `->disk()`, `->directory()`, `->maxFiles()`, …) works unchanged
- **Zero build step** — no npm, no Vite, no esbuild; pure Blade + Alpine.js inline
- **Reorder-safe** — captions follow their image through drag-and-drop reordering
- **Duplicate-filename safe** — maps FilePond internal IDs to Filament UUIDs directly, so ten files all named `banner.jpg` each keep their own caption
- **Race-condition safe** — captions typed before an upload finishes are preserved and migrated to the final UUID automatically
- **Simple storage** — saved as a plain `[{image, caption}]` JSON array in a single column; no extra tables or relationships needed

---

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 10+
- Filament 3.x

---

Installation
------------

[](#installation)

Choose the version that matches your Filament installation:

FilamentVersion3.x`^1.0`4.x`^2.0`5.x`^3.0````
# Filament 3.x
composer require imsyuan/filament-image-caption-upload "^1.0"

# Filament 4.x
composer require imsyuan/filament-image-caption-upload "^2.0"

# Filament 5.x
composer require imsyuan/filament-image-caption-upload "^3.0"
```

Laravel auto-discovers the service provider — no manual registration needed.

---

Usage
-----

[](#usage)

```
use Imsyuan\ImageCaptionUpload\Forms\Components\ImageCaptionUpload;

ImageCaptionUpload::make('photos')
    ->multiple()
    ->image()
    ->reorderable()
    ->captionPlaceholder('Enter a caption…'),
```

Cast the column as an array in your model:

```
// app/Models/Post.php
protected $casts = [
    'photos' => 'array',
];
```

Each field saves an array of `{image, caption}` pairs:

```
[
  { "image": "photos/living-room.jpg", "caption": "Living room view" },
  { "image": "photos/kitchen.jpg",     "caption": "Kitchen detail" }
]
```

---

Options
-------

[](#options)

### `captionPlaceholder(string|Closure $placeholder)`

[](#captionplaceholderstringclosure-placeholder)

Sets the placeholder text shown inside each caption input. Accepts a plain string or a closure. Defaults to `'Caption...'`.

```
// Static
->captionPlaceholder('Add a description…')

// Dynamic
->captionPlaceholder(fn () => __('fields.caption_placeholder'))
```

### All native `FileUpload` options

[](#all-native-fileupload-options)

Because `ImageCaptionUpload` extends Filament's `FileUpload` directly, every built-in option is available:

```
ImageCaptionUpload::make('photos')
    ->multiple()
    ->image()
    ->maxFiles(10)
    ->reorderable()
    ->appendFiles()
    ->disk('s3')
    ->directory('photos')
    ->visibility('public')
    ->panelLayout('grid')
    ->imageResizeMode('cover')
    ->imageResizeTargetWidth('400')
    ->imageResizeTargetHeight('400'),
```

---

How it works
------------

[](#how-it-works)

1. **Hydration** — `[{image, caption}]` from the database is split on load: file paths go into Filament's UUID-keyed state; captions are stored in a sibling Livewire key (`_icap_`).
2. **Alpine** — A `MutationObserver` watches for FilePond item additions and injects a caption `` beneath each file panel. Typing syncs directly to Livewire state via `$wire.set()`.
3. **UUID mapping** — FilePond's internal IDs are mapped to Filament UUIDs by reading the FilePond instance directly (`pond.getFiles()`), ensuring correctness regardless of stored filename or UUID-based disk naming.
4. **Dehydration** — On save, `{uuid: path}` and `{uuid: caption}` are zipped back into `[{image, caption}]`.

---

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance92

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

7

Last Release

41d ago

Major Versions

1.1.1 → 2.0.12026-06-15

2.0.1 → 3.0.12026-06-15

3.0.1 → 4.x-dev2026-06-15

4.x-dev → 5.x-dev2026-06-15

PHP version history (2 changes)1.0.0PHP ^8.1

1.1.0PHP ^8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/8586464?v=4)[Steven.Chang](/maintainers/imsyuan)[@imsyuan](https://github.com/imsyuan)

---

Top Contributors

[![imsyuan](https://avatars.githubusercontent.com/u/8586464?v=4)](https://github.com/imsyuan "imsyuan (13 commits)")

---

Tags

filamentfilamentphpfile-uploadlaravellivewirelaravelimagefile-uploadfilamentfilamentphpcaption

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/imsyuan-filament-image-caption-upload/health.svg)

```
[![Health](https://phpackages.com/badges/imsyuan-filament-image-caption-upload/health.svg)](https://phpackages.com/packages/imsyuan-filament-image-caption-upload)
```

###  Alternatives

[danihidayatx/image-optimizer

Optimize your Filament images before they reach your database. Forked from joshembling/image-optimizer for Filament v4 &amp; v5 support.

3418.1k](/packages/danihidayatx-image-optimizer)[codewithdennis/filament-select-tree

The multi-level select field enables you to make single selections from a predefined list of options that are organized into multiple levels or depths.

330530.5k30](/packages/codewithdennis-filament-select-tree)[joshembling/image-optimizer

Optimize your Filament images before they reach your database.

113163.0k12](/packages/joshembling-image-optimizer)[awcodes/filament-curator

A media picker plugin for FilamentPHP.

437356.9k25](/packages/awcodes-filament-curator)[awcodes/richer-editor

A collection of extensions and tools to enhance the Filament Rich Editor field.

3913.8k9](/packages/awcodes-richer-editor)[marcelweidum/filament-passkeys

Use passkeys in your filamentphp app

6649.5k2](/packages/marcelweidum-filament-passkeys)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
