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

Filament Copyable Laravel Package

saadj55/filament-copyable

A Filament plugin that makes table columns and text click-to-copy, letting users copy values to the clipboard instantly. Simple to install and configure, it adds handy copy actions and icons to Filament admin panels and resource tables.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and pin against your Filament major version first. The package's feature work dates to October 2022, which puts it squarely in the Filament v2 era. The most recent release, v0.1.4, is a metadata-only patch ("fix composer version") — it does not signal a v3 compatibility refresh. Before writing any code:

composer require saadj55/filament-copyable
composer show saadj55/filament-copyable   # inspect the filament/* constraint it declares

That composer show step matters more than usual right now: v0.1.4's only change is to composer version metadata, so the declared filament/filament constraint may have shifted even though nothing in src/ did. Read the constraint, don't infer it from the README.

If your app is on Filament v3, treat the install as a spike, not a decision. Verify that the service provider registers, that the classes resolve, and that a single column renders before touching production resources.

Where to look first, in order:

  1. composer.json in the package — the filament/filament constraint tells you compatibility faster than any README. This is the file v0.1.4 touched, so check it on the exact tag you install.
  2. src/ — identify whether the package ships dedicated column/field classes (CopyableColumn, CopyableEntry, etc.) or macros/opt-in methods on the stock TextColumn. This determines every snippet you write afterwards.
  3. resources/views/ — the copy button is Blade + Alpine; this is where you customize icon, tooltip, and styling.
  4. Any config/filament-copyable.php — check for publishable config (tooltip text, icon, timeout).

First use case: identifiers in a table. The canonical reason to install this is that users are hand-selecting 36-character UUIDs with a mouse. Start with one column:

// Variant A — dedicated class
use Saadj55\FilamentCopyable\Tables\Columns\CopyableColumn;

CopyableColumn::make('order_number'),

// Variant B — opt-in method on the stock column
TextColumn::make('order_number')->copyable(),

Pick whichever your src/ inspection revealed, ship it on one resource, and confirm the button appears and the clipboard payload is the full value (see Gotchas). Only then roll it out.

Implementation Patterns

Identifiers and machine-readable strings. Order numbers, invoice references, tracking codes, IBANs, Stripe IDs, webhook secrets, invite tokens. This is 90% of the package's value and where to spend your rollout effort.

Form fields for generated values. The second-highest-value case: an API key or personal access token shown once after creation. Render it in a disabled() / readOnly() field so the user can copy without editing:

TextInput::make('api_token')
    ->readOnly()
    ->copyable()          // or the package's dedicated field class
    ->columnSpanFull(),

Wrap this in a Notification or modal flow rather than a normal edit form, so the secret isn't re-readable on every visit.

Copy the raw value, display the formatted value. This is the single most important pattern. Tables routinely truncate or reformat:

TextColumn::make('uuid')
    ->limit(8)            // display only
    ->copyable(),         // must still yield the full UUID

Verify by copying a truncated-looking cell and pasting into a scratch file. If the package copies the rendered string, you must either drop ->limit() or pass the raw value explicitly. Do this verification once per column type (money, dateTime, badge) rather than assuming.

Pair with visibility and policy gates for anything sensitive. A copy button is a data-exfiltration accelerator. For tokens and PII:

CopyableColumn::make('api_secret')
    ->visible(fn () => auth()->user()->can('viewSecret', $record)),

Prefer ->visible() over CSS hiding — a hidden-but-rendered value is still in the DOM.

Standardize with a base resource. Once you've settled on a class name and options, add a small helper on your base resource or a trait so copyable() is one word everywhere and you can swap implementations when the package is abandoned:

protected static function copyableId(string $name): TextColumn
{
    return CopyableColumn::make($name)->tooltip('Copy')->icon('heroicon-o-clipboard');
}

If the package's options run out, drop to Alpine. A copy button is ~10 lines; don't fight the package for a one-off:

<span x-data="{ copied: false }">
    <button type="button"
        x-on:click="navigator.clipboard.writeText(@js($value)); copied = true; setTimeout(() => copied = false, 1500)">
        <x-heroicon-o-clipboard class="w-4 h-4" />
    </button>
</span>

Testing. Livewire's assertSee proves the button rendered; it proves nothing about the clipboard. Use Dusk or a browser test with clipboard permissions granted to assert the actual write.

Gotchas and Tips

Filament major-version drift is the headline risk. The feature code predates Filament v3's namespace and column API changes, and v0.1.4 fixes composer version metadata rather than compatibility. If you're on v3, budget an hour for a failed install or a fork; don't discover it mid-sprint. If it works, pin the version in composer.json and add a note in your upgrade checklist.

Re-run composer show after a patch bump. Because v0.1.4's sole change is to the composer manifest, a composer update can move your resolved package without any PHP changing, and a loosened constraint can pull a different Filament major. Pin exactly rather than relying on ^0.1; if you've forked or pinned to 0.1.3, confirm whether the constraint fix actually affects you before chasing the upgrade.

navigator.clipboard requires a secure context. It works on https:// and localhost, and silently fails on http://192.168.x.x — which is exactly the URL your QA person will use on a phone. Test on a real device over HTTPS, or ensure the package has an execCommand fallback. Add a visible "Copied!" state so a failure is distinguishable from a success.

Display value ≠ copied value. Covered above, but repeat it: ->limit(), ->formatStateUsing(), ->money(), and ->badge() all change what's on screen. Audit each copyable column once.

Alpine state and Livewire re-renders. Table sorting, searching, and pagination re-render rows. If the copied/checkmark state lives outside the row's x-data scope, it will either persist wrongly or reset mid-animation. Keep the x-data on the element that owns the button.

Asset and style registration. Filament v2 packages typically register their own CSS/JS via a service provider. If the button renders unstyled or the icon is missing, check that the provider was auto-discovered (php artisan package:discover) and that you published views if you want to customize:

php artisan vendor:publish --tag=filament-copyable-views

Localization. The tooltip "Copied!" is almost certainly hardcoded English in the Blade. If you're shipping a non-English admin, publish the views and swap for __('...') — it's ten minutes now versus a bug report later.

Performance on large tables. Each row gets a button; at 50 rows per page this is fine, but a copy button on a ->searchable() high-traffic column adds DOM weight. Nothing to fix, just don't put copyable buttons on five columns at once.

Sensitive data hygiene. Copying a token puts it in the OS clipboard, where clipboard managers and other apps can read it. For secrets, prefer a "reveal + copy" flow with an expiry, and never make the column searchable() or log it.

Have an exit plan. Thirty-six stars, zero dependents, no feature release in over two years, and a v0.1.4 that only touches packaging metadata — this is a package you should be prepared to replace. Keeping the button behind your own copyableId() helper (above) means replacing it is a one-file change instead of a find-and-replace across forty resources.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console