osama/image-paste
A Laravel package for handling images pasted from the clipboard into forms or rich-text editors. It processes pasted image data, stores uploads, and returns usable file paths or URLs, simplifying clipboard image support in PHP applications.
The package is a Nova field that extends the standard upload experience with drag-and-drop and clipboard paste support. Before anything else, confirm it's reachable on Packagist and that the composer.json require block lists a Nova version you're actually on (Nova 4 vs. Nova 5 APIs diverge). Since it sits at 1 star with no dependents, treat the install as a spike, not a commitment.
Minimal steps:
composer require osama/image-paste
If the package ships compiled assets, run php artisan nova:publish (Nova fields typically need this to expose their JS/CSS to the Nova frontend).
Drop the field into a resource's fields() method in place of your existing Image field:
use Osama\ImagePaste\ImagePaste; // verify namespace from the source
public function fields(NovaRequest $request)
{
return [
ImagePaste::make('Avatar')
->disk('public')
->path('avatars')
->rules('image', 'max:2048'),
];
}
First use case to validate end-to-end: a single-image field on a model the team edits frequently (user avatar, post cover, product thumbnail). That gives you a real upload flow to test against — drag a file in, then paste a screenshot from your clipboard — without gambling on a critical resource.
Where to look first: open the package's src/ directory and read the field class. It should extend Laravel\Nova\Fields\Image (or File). If it reimplements upload logic from scratch instead of extending Nova's field, expect compatibility drift with every Nova minor release. Also inspect dist/ or resources/js/ for the paste handler — that's where the actual feature lives.
Drop-in replacement for Image. The lowest-risk integration is to treat it as a decorator: use identical ->disk(), ->path(), ->storeAs(), ->prunable(), ->rules() chains you'd use on a normal Nova Image field. If the package correctly extends Image, these should pass through untouched. Test one field this way before rolling it out.
Paste-for-screenshot workflow. The killer use case is CMS-style editing: editors paste screenshots straight from Slack/Figma into a "Cover Image" field instead of saving to disk first. Pair it with a predictable path so you can reason about storage:
ImagePaste::make('Cover')
->disk('s3')
->path('covers/'.now()->format('Y/m'))
->rules('required', 'image', 'max:5120', 'dimensions:min_width=1200');
Multi-field resources. If you have several image fields on one form, verify the paste handler is scoped to the focused field and not the document body — a global paste listener will dump the clipboard image into whichever field registered last. Test with two image fields visible at once.
Custom Nova tools and cards. Because it's a field, it composes inside any Resource or Action modal. For bulk workflows, prefer a File-style action with ->rules() and reuse the same disk/path conventions so the paste field and your actions write to consistent locations.
Storage integration. Point the disk at your CDN-backed bucket and let Nova's ->thumbnail() callback handle previews. If files land at S3 but thumbnails use local assert, add ->preview(fn ($value, $disk) => Storage::disk($disk)->url($value)).
composer.json Nova constraint, the JS for fetch/FormData upload logic, and whether it uses Nova's Nova.request() (auth + CSRF handled) or a raw axios/fetch call (you'll get 419s).mix-based asset pipeline often break silently on Nova 4/5's Vite build. If nova:publish produces no js/field.js, the field will render but the paste handler won't load — check the browser console for a 404 on the field's asset.npm run dev in the host app. Every deploy after a package update needs php artisan nova:publish (or vendor:publish --tag=nova-assets) or you'll test stale JS.image/png from ClipboardEvent.clipboardData.items; File selection from a drag may be image/jpeg or image/webp. If your ->rules() use mimes:jpeg,png, paste workflows will fail for WebP screenshots on newer OSes. Use image instead.->rules() yourself; never trust that the field sets defaults. Missing rules = unvalidated uploads.screenshot.png every time). Confirm storeAs/storeOriginalName behavior, or wrap with ->storeAs(fn ($request, $file) => Str::uuid().'.'.$file->extension()) to avoid silent overwrites.Image and add a paste handler," you're probably better off vendoring the JS into your own custom field (php artisan nova:field) — you get the same UX, plus maintenance control, which matters more than saving a day on a 1-star dependency.POST, (3) the field's wrapper element doesn't have tabindex so it never receives focus/paste events, (4) Nova's Image field renders <input type=file> and the package's listener is bound to the wrong element.How can I help you explore Laravel packages today?