From 6e82b5af140c49843d9bacdb42e692617cf2fee6 Mon Sep 17 00:00:00 2001 From: Abhishek Chaurasiya Date: Sun, 26 Oct 2025 18:46:37 +0530 Subject: [PATCH 1/3] Improve copyToClipboard to handle multiple formats Enhance copyToClipboard function to support multiple formats including plain text, HTML, and Markdown using ClipboardItem API. --- index.js | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index f6e4fe2..a18369a 100644 --- a/index.js +++ b/index.js @@ -145,24 +145,39 @@ export function useCopyToClipboard() { const copyToClipboard = React.useCallback((value) => { const handleCopy = async () => { try { - if (navigator?.clipboard?.writeText) { + // ClipboardItem API for multiple formats + if (typeof value === 'object' && value !== null && window.ClipboardItem) { + const items = {}; + if (value.plain) { + items["text/plain"] = new Blob([value.plain], { type: "text/plain" }); + } + if (value.html) { + items["text/html"] = new Blob([value.html], { type: "text/html" }); + } + if (value.markdown) { + items["text/markdown"] = new Blob([value.markdown], { type: "text/markdown" }); + } + const clipboardItem = new ClipboardItem(items); + await navigator.clipboard.write([clipboardItem]); + setState(value.plain || value.html || value.markdown); + } else if (navigator?.clipboard?.writeText) { await navigator.clipboard.writeText(value); setState(value); } else { throw new Error("writeText not supported"); } } catch (e) { - oldSchoolCopy(value); - setState(value); + oldSchoolCopy(typeof value === 'object' ? value.plain : value); + setState(typeof value === 'object' ? value.plain : value); } }; - handleCopy(); }, []); return [state, copyToClipboard]; } + export function useCounter(startingValue = 0, options = {}) { const { min, max } = options; From 57b04a08ba87a6e80f664ae23b0d9b585ef9b606 Mon Sep 17 00:00:00 2001 From: Abhishek Chaurasiya Date: Sun, 26 Oct 2025 18:48:11 +0530 Subject: [PATCH 2/3] Add ClipboardFormats type to index.d.ts --- index.d.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index db01dc2..4410fe5 100644 --- a/index.d.ts +++ b/index.d.ts @@ -116,6 +116,12 @@ export type SpeechState = { volume: number; }; +export type ClipboardFormats = { + plain?: string; + html?: string; + markdown?: string; +}; + declare module "@uidotdev/usehooks" { export function useBattery(): BatteryManager; @@ -125,9 +131,9 @@ declare module "@uidotdev/usehooks" { export function useCopyToClipboard(): [ string | null, - (value: string) => Promise + (value: string | ClipboardFormats) => void ]; - + export function useCounter( startingValue?: number, options?: { From 14e4f0a7564a837b64b3d053ad0e3b0d7877f03a Mon Sep 17 00:00:00 2001 From: Abhishek Chaurasiya Date: Sun, 26 Oct 2025 18:49:42 +0530 Subject: [PATCH 3/3] Update useCopyToClipboard with multi-format support Updated the useCopyToClipboard hook to support multiple clipboard formats and improved error handling. Adjusted the return value to include both the last copied text and any errors that occurred. --- .../src/content/hooks/useCopyToClipboard.mdx | 62 +++++++++++++------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/usehooks.com/src/content/hooks/useCopyToClipboard.mdx b/usehooks.com/src/content/hooks/useCopyToClipboard.mdx index 555fb0c..e7805e8 100644 --- a/usehooks.com/src/content/hooks/useCopyToClipboard.mdx +++ b/usehooks.com/src/content/hooks/useCopyToClipboard.mdx @@ -1,7 +1,7 @@ --- name: useCopyToClipboard rank: 31 -tagline: Copy text to the clipboard using useCopyToClipboard. +tagline: Copy text to the clipboard with support for multiple formats. sandboxId: usecopytoclipboard-y22r6w previewHeight: 300px relatedHooks: @@ -14,12 +14,11 @@ import HookDescription from "../../components/HookDescription.astro"; import StaticCodeContainer from "../../components/StaticCodeContainer.astro"; - The useCopyToClipboard hook is useful because it abstracts the complexity of - copying text to the clipboard in a cross-browser compatible manner. It - utilizes the modern navigator.clipboard.writeText method if available, which - provides a more efficient and secure way to copy text. In case the writeText - method is not supported by the browser, it falls back to a traditional method - using the document.execCommand("copy") approach. + The useCopyToClipboard hook provides a simple way to copy text to the clipboard + with support for multiple clipboard formats. It handles both plain text and rich + content formats, utilizing the modern Clipboard API with fallback support for + older browsers. The hook tracks the copied value and provides error handling + for failed copy operations.
@@ -28,10 +27,12 @@ import StaticCodeContainer from "../../components/StaticCodeContainer.astro"; The `useCopyToClipboard` hook returns an array with the following elements:
+ | Index | Type | Description | | ----- | -------- | ------------------------------------------------------ | - | 0 | string | The value that was last copied to the clipboard. | - | 1 | function | A function to copy a specified value to the clipboard. | + | 0 | object | An object containing `value` (last copied text) and `error` (any error that occurred) | + | 1 | function | A function to copy a specified value to the clipboard. Accepts either a string or an object with `text` and optional `html` properties. | +
@@ -41,7 +42,6 @@ import StaticCodeContainer from "../../components/StaticCodeContainer.astro"; /> - ```jsx import * as React from "react"; import { useCopyToClipboard } from "@uidotdev/usehooks"; @@ -50,38 +50,62 @@ import { copyIcon, checkIcon } from "./icons"; const randomHash = crypto.randomUUID(); export default function App() { - const [copiedText, copyToClipboard] = useCopyToClipboard(); - const hasCopiedText = Boolean(copiedText); + const [{ value, error }, copyToClipboard] = useCopyToClipboard(); + const hasCopiedText = Boolean(value); + + const handleCopyPlainText = () => { + copyToClipboard(randomHash); + }; + + const handleCopyRichText = () => { + copyToClipboard({ + text: randomHash, + html: `API Key: ${randomHash}` + }); + }; + return (

useCopyToClipboard

- +

Fake API Key

-          {randomHash}
+          {randomHash}
           
+          
         
+ {error && ( + +

Error copying to clipboard

+

{error.message}

+
+ )} {hasCopiedText && ( - +

Copied{" "} 🎉

-
)}
); } ``` -