Summary#
Clipboard.Copy(text) writes a string to the visitor's system clipboard. It is available in every component, and it
is the whole surface: one verb, one argument.
It exists because "copy this" is a browser act with no server equivalent — the clipboard belongs to the person at the keyboard, not to your app or to the machine your app runs on. So it is a verb, alongside Navigation's and theme tokens's, rather than a function you could call from a server body.
The platform ships no copy button. Where it lives, what it looks like, and whether it says "Copied!" afterwards are your layout's decisions.
Signature#
Clipboard.Copy(text) // put `text` on the system clipboard; returns nothingDescription#
Copying text — where the call goes#
It is an ordinary statement in an action body:
component ShareLink(string Url) {
action Copy() { Clipboard.Copy(Url); }
render {
Row {
Text(Url);
Button("Copy", onPress: Copy);
}
}
}Showing a "Copied!" — the feedback is yours#
The verb returns nothing, so the "Copied!" is yours to render — which is what you want, because the wording, the placement and how long it lingers are design decisions. Set your own state on the click:
component CopyKey(string Key) {
bool copied = false;
action Copy() {
Clipboard.Copy(Key);
copied = true;
}
render {
Button(copied ? "Copied!" : "Copy key", onPress: Copy);
}
}The text goes across verbatim#
Whatever you pass is what lands on the clipboard, byte for byte. Nothing is escaped, trimmed, or rewritten — a code
snippet containing <script> arrives as those nine characters, because a clipboard is not a rendering surface and
"helpfully" sanitizing it would corrupt the very thing someone asked to copy.
That also means you decide what is copyable. Copying a value your visitor cannot see is not a boundary the clipboard enforces; the ordinary rules about what a component may read still apply, and they apply here unchanged.
When it cannot copy#
A browser may refuse a clipboard write — most often because the page is served over plain http from an address that
is not localhost, where the modern clipboard API does not exist at all. The platform falls back to the older
selection-based copy, which works there, so a copy button on an internal http-only deployment still functions.
If both paths fail, nothing is copied and the browser console says so, naming the reason. The action itself carries on: a refused copy never throws and never aborts the rest of your body.
Can I READ the clipboard? No#
There is no Clipboard.Read. Reading someone's clipboard is a permission-gated act with a prompt attached, and
nothing in the platform needs it — a paste arrives through an ordinary Input the moment the visitor presses the
keys. If you have a case that genuinely needs it, that is a conversation to have rather than a gap to work around.
Can I name something Clipboard? — shadowing#
Clipboard is an ambient name, so an identifier of your own wins — a parameter, a state member or a variable called
Clipboard shadows it, exactly as it does for Navigation and theme tokens. Nothing you already named breaks
because this verb exists.
Copying from rendered markdown#
A Markdown(...) document renders inside the atom, so your app cannot reach the code blocks inside it to hang a
button on them. That case has its own opt-in — see Markdown — rendering markdown text #code-actions, which renders a copy control per
code block using an icon and tooltip you supply.
See also#
- Markdown — rendering markdown text — per-code-block copy inside a rendered document
- Navigation — the other browser verbs (
Go,Open,Close) - theme tokens —
Theme.Toggle()/Theme.Set(mode), the same shape - component — where actions live