shadcn.io is an independent project built on shadcn/ui
useCopyToClipboard returns a copy function and an isCopied flag that turns on after a successful write.
Use it on a copy button, a code block, or a share link. The flag flips back on its own, so you don't need useTimeout for that two-second reset. In React the copy function stays the same between renders.
Installation
Anatomy

Usage
import { useCopyToClipboard } from "@/hooks/use-copy-to-clipboard";const [copy, isCopied] = useCopyToClipboard();isCopied becomes true after a successful copy and returns to false two seconds later.
FAQ
Which API does the copy use?
It writes the string with navigator.clipboard.writeText. If navigator.clipboard is missing, the function logs a warning and returns without throwing. There is no document.execCommand fallback in this hook. A successful write sets the copied flag to true, and a rejected write logs a warning and sets that flag to false.
Can I change how long the copied flag stays on?
Not with an argument. The reset is a setTimeout of 2000 milliseconds inside the hook, and nothing you pass can change it. Call copy again and a second timer is scheduled too. The flag simply goes false when a timer fires, even if a newer copy just succeeded.
Can I copy an object?
Only as text. copy takes a string and passes that string to writeText. Turn an object into text yourself before the call, for example with JSON.stringify. The hook does not format JSON, and it does not accept a number or an object in its type.
What happens when the copy fails?
The error is caught. The hook logs Copy failed with the error and sets the flag to false. It does not rethrow, so the click handler does not need its own try block for that rejection. If the clipboard is missing entirely, it logs Clipboard not supported and leaves the flag as it was.
Is useCopyToClipboard safe on the server?
Yes. Nothing in the hook reads window during render. navigator.clipboard is only touched when copy runs, which is a click on the client. The flag starts as false on both server and client, so the first paint matches. A server render does not try to write the clipboard.
API Reference
Returns
[0] copy(text: string) => Promise<void>
Writes the text to the clipboard (navigator.clipboard.writeText). Resolves either way; a failure, or a browser without the Clipboard API, logs a warning. /
- Type
(text: string) => Promise<void>
[1] isCopiedboolean
true for 2 seconds after a successful copy, then false again.











