This hook provides a simple method to copy a string to the clipboard and keeps track of the copied value. If the copying process encounters an issue, it logs a warning in the console, and the copied value remains null.
Usage
import { useCopyToClipboard } from './useCopyToClipboard'
export default function Component() {
const [copiedText, copy] = useCopyToClipboard()
const handleCopy = (text: string) => () => {
copy(text)
.then(() => {
console.log('Copied!', { text })
})
.catch(error => {
console.error('Failed to copy!', error)
})
}
return (
<>
<h1>Click to copy:</h1>
<div style={{ display: 'flex' }}>
<button onClick={handleCopy('A')}>A</button>
<button onClick={handleCopy('B')}>B</button>
<button onClick={handleCopy('C')}>C</button>
</div>
<p>Copied value: {copiedText ?? 'Nothing is copied yet!'}</p>
</>
)
}
API
function useCopyToClipboard(): unknown
Custom hook that copies text to the clipboard using the Clipboard API.
Returns
An tuple containing the copied text and a function to copy text to the clipboard.
Type declaration
CopiedValue
The copied text as string or null if nothing has been copied yet.
CopyFn
Function to copy text to the clipboard.
Hook
import { useCallback, useState } from 'react'
/**
* The copied text as `string` or `null` if nothing has been copied yet.
*/
export type CopiedValue = string | null
/**
* Function to copy text to the clipboard.
* @param text - The text to copy to the clipboard.
* @returns {Promise<boolean>} A promise that resolves to `true` if the text was copied successfully, or `false` otherwise.
*/
export type CopyFn = (text: string) => Promise<boolean>
/**
* Custom hook that copies text to the clipboard using the [`Clipboard API`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API).
* @returns {[CopiedValue, CopyFn]} An tuple containing the copied text and a function to copy text to the clipboard.
* @public
* @see [Documentation](https://usehooks-ts.com/react-hook/use-copy-to-clipboard)
* @example
* ```tsx
* const [copiedText, copyToClipboard] = useCopyToClipboard();
* const textToCopy = 'Hello, world!';
*
* // Attempt to copy text to the clipboard
* copyToClipboard(textToCopy)
* .then(success => {
* if (success) {
* console.log(`Text "${textToCopy}" copied to clipboard successfully.`);
* } else {
* console.error('Failed to copy text to clipboard.');
* }
* });
* ```
*/
export function useCopyToClipboard(): [CopiedValue, CopyFn] {
const [copiedText, setCopiedText] = useState<CopiedValue>(null)
const copy: CopyFn = useCallback(async text => {
if (!navigator?.clipboard) {
console.warn('Clipboard not supported')
return false
}
// Try to save to clipboard then save it in the state if worked
try {
await navigator.clipboard.writeText(text)
setCopiedText(text)
return true
} catch (error) {
console.warn('Copy failed', error)
setCopiedText(null)
return false
}
}, [])
return [copiedText, copy]
}