sixlive/nova-text-copy-field
A Laravel Nova field that displays text with a one-click copy-to-clipboard button, making it easy for users to grab URLs, IDs, tokens, and other values from the admin panel without manual selection. Simple to install and customize.
Architecture fit. sixlive/nova-text-copy-field is a single-purpose Nova field package: one PHP field class extending Laravel\Nova\Fields\Text, a pre-compiled Vue bundle in dist/, and a TextCopy::make() API that mirrors Nova's native field ergonomics. Architecturally it is the lowest-friction shape a Nova extension can take — no service provider, no config publish, no migration, no routes, no middleware. It slots into fields(Request $request) exactly where Text::make() sits today and is reversible one line at a time. The relevant architectural question is not "does it fit" (it does, trivially) but "is a third-party Vue field bundle an acceptable dependency in our admin plane at all" — and the answer should be a standing policy, not a per-ticket debate.
Integration feasibility. High on the PHP side, uncertain on the frontend side, and the asymmetry is the whole evaluation. The PHP class is a thin subclass and reading it end-to-end takes minutes. The Vue component is where the risk lives: it was authored against Nova 3's Vue 2 field contract, and Nova 4+ moved to Vue 3. Nova loads whatever is in dist/, so resources/js and dist/ being out of sync — common in single-maintainer packages — means dist/ is the source of truth and may not match the repository's visible source. Feasibility is therefore gated on one empirical test: install in a dev environment on our Nova major and confirm the field renders with a functional button on index, detail, create, and edit. That is an afternoon, not a project.
Technical risk. Three risks, in order of likelihood:
navigator.clipboard requires a secure context. Over plain HTTP — including internal/staging environments reached by IP — the modern Clipboard API is unavailable, and if there is no execCommand fallback the button does nothing with no error. This produces support tickets that read as bugs and aren't.The mitigating factor for all three: the blast radius is one field in one admin panel. This is not on a request path, not in the data plane, and not a security control. Failure mode is "operators fall back to manual text selection."
Key questions.
IndexField; confirm rather than assume.CopyableValue wrapper now, so a future swap is one file rather than N resources?Stack fit. Correct stack, correct layer. PHP ^7/^8 with Laravel and Nova is the native habitat; the package adds a field, not a subsystem. Composer-only install, no bootstrap ceremony. If we are on Nova 3, fit is essentially guaranteed. If we are on Nova 4+, fit is plausible but unproven and must be demonstrated before it enters a resource.
Migration path. Deliberately incremental and deliberately reversible. The migration is a one-line swap per field:
// was: use Laravel\Nova\Fields\Text;
use Sixlive\TextCopy\TextCopy;
TextCopy::make('External Account ID', 'external_account_id')
->onlyOnDetail()
->readonly(),
Pick one resource, one read-only value the team genuinely transcribes — an external account ID, a slug, a public invite URL. Verify on the detail view first. Then, and only then, expand. Do not batch-migrate fields across resources; the value of this package is that adoption is granular and rollback is a use statement.
Compatibility. Two axes:
php artisan nova:field acme/copyable-text and porting roughly 100 lines. Both are hours, not days. What we must not do is discover this mid-rollout.Text behaviors do not automatically carry. displayUsing(), asHtml(), truncation, and withMeta() props may be unimplemented — the component author's props, not Nova's, decide. Read resources/js/components/ and use only what is actually forwarded. When a resource needs something the component doesn't support, use plain Text and accept the missing button rather than hacking around it in the resource.Sequencing.
vendor/sixlive/nova-text-copy-field/composer.json constraints; confirm Nova major compatibility target."sixlive/nova-text-copy-field": "1.5.0" — not ^1.5) in dev. Run the matrix per context — index, detail, create, edit — over HTTPS and, if any environment is plain HTTP, over HTTP, to learn what silent failure looks like. Watch the browser console once; a 404 on the field bundle is a two-second diagnosis.App\Nova\Fields\CopyableValue extending the package class and standardize on it. This is the convention decision, and it is worth making regardless of which implementation ultimately wins — it also converts a package swap into a single-file edit.Where the "generate, then copy" flow is required — API tokens, webhook secrets shown once — generate the value in a model observer (creating/saving), scope the field ->onlyOnDetail()->readonly(), and route the operator to the detail view. On create forms an empty column yields an empty copy, which is the second-most-common surprise after Nova-version breakage.
Maintenance. Near-zero steady-state, non-zero at upgrade events. The package has no release since March 2019 and no realistic upstream support path, so maintenance is our maintenance. The honest register entry is "disposable": review on every Nova major upgrade, with a pre-agreed disposition of either patch-the-component or replace-with-native-field. Budget hours, not days, at each upgrade boundary. The single best maintenance investment is the CopyableValue wrapper introduced on day one — it collapses N potential fixes into one file.
Support. The support load is front-loaded into a small number of well-understood tickets:
nova:publish, hard refresh, confirm the component is rendering as a custom component and not degrading to plain text. Nova caches assets in public/vendor/ and browsers cache the bundle aggressively; most reports are stale assets.Document these three diagnoses in the internal runbook. They cover the overwhelming majority of inbound reports and prevent the package from acquiring a reputation as flaky when the causes are environmental.
Scaling. Effectively unlimited in the dimension that matters — this is a UI affordance on an admin read path, not a throughput component. It scales to more resources by repetition, which is precisely why the wrapper convention matters: without it, scope creep across resources becomes inconsistent configuration drift. The scaling constraint is governance, not performance: the more places a copy-to-clipboard button appears, the more likely a reviewer assumes sensitive values are "handled." That assumption is the thing to manage.
Failure modes.
| Mode | Symptom | Blast radius | Mitigation |
|---|---|---|---|
| Nova major mismatch | Field renders as plain text, or asset build fails | One field, one resource | Empirical dev smoke test before adoption; wrapper as exit ramp |
| Insecure context | Button silently no-ops | All copy actions in that environment | Enforce HTTPS; verify an execCommand fallback exists |
| Empty value on create | Copies "" |
Operator confusion, possible pasted blanks into configs | Generate in observer; scope ->onlyOnDetail() |
dist/ out of sync with resources/js |
Unpredictable component behavior | Field only | Treat dist/ as source of truth; read it before relying on any prop |
| Accessibility gaps | Icon-only button not focusable, unlabeled, color-only success state | Operators using keyboard/screen readers | Hand-check once: tab focus, screen-reader label, non-color success indicator |
| Scope mispositioning | Treated as a secrets control | Governance, not technical | Explicit boundary: convenience-sensitive, not classified |
The last row is the only one that can escalate beyond the field itself. Position this package as an anti-transcription-error affordance for IDs, public links, and short-lived keys — never as masking, reveal-on-demand, audit, or rotation. If a value is genuinely sensitive, the correct design is a masked/truncated display with an explicit reveal action, and ideally the secret stays out of Nova fields entirely.
Ramp-up. Trivial for any Laravel/Nova developer. The API is TextCopy::make(), the field class is short, and Nova's standard visibility modifiers (onlyOnDetail, exceptOnForms, canSee, readonly, help) do the configuration work. Expect under an hour for a developer already fluent in Nova resources. The ramp-up cost that is real is organizational: someone must own the upgrade-review trigger and the dependency-register entry, and that ownership has to be assigned at adoption, not discovered at the next Nova upgrade.
How can I help you explore Laravel packages today?