Snippet
Copy Button
Copying text to your clipboard.
Credit
Pulled from the shadcn-ui/ui repo.
Demo
Icon only
With text
Usage
Icon only
import { CopyButton } from '@/components/copy-button'
const Page = () => {
return <CopyButton />
}
export default Page
With text
import { CopyButton } from '@/components/copy-button'
const Page = () => {
return <CopyButton>Custom Text</CopyButton>
}
export default Page
Source Code
'use client'
import * as React from 'react'
import { CheckIcon, ClipboardIcon } from 'lucide-react'
import { cn } from '@/lib/utils'
import { toast } from 'sonner'
import { Button, type ButtonProps } from '../ui/button'
interface CopyButtonProps extends ButtonProps {
value: string
}
export async function copyToClipboard(value: string) {
navigator.clipboard.writeText(value)
toast.success('Copied to clipboard')
}
export function CopyButton({ value, className, children, ...props }: CopyButtonProps) {
const [hasCopied, setHasCopied] = React.useState(false)
React.useEffect(() => {
setTimeout(() => {
setHasCopied(false)
}, 2000)
}, [hasCopied])
if (children) {
return (
<Button
variant='outline'
onClick={() => {
copyToClipboard(value)
setHasCopied(true)
}}
{...props}
>
{hasCopied ? <CheckIcon /> : <ClipboardIcon />}
<span>{children}</span>
</Button>
)
}
return (
<Button
size='icon'
variant='outline'
className={cn('relative z-10 size-8 [&_svg]:size-4', className)}
onClick={() => {
copyToClipboard(value)
setHasCopied(true)
}}
{...props}
>
<span className='sr-only'>Copy</span>
{hasCopied ? <CheckIcon /> : <ClipboardIcon />}
</Button>
)
}