Skip to content

Commit 57b5a1e

Browse files
committed
fix: add clipboard fallback for code block copy in web UI
The Clipboard API (navigator.clipboard.writeText) requires a secure context (HTTPS or localhost). When the web UI is accessed over plain HTTP or on platforms without clipboard support (e.g., Termux), the copy button silently fails. Add a fallback using document.execCommand('copy') with a temporary textarea element for non-secure contexts. Fixes #1340
1 parent 7ba9695 commit 57b5a1e

1 file changed

Lines changed: 20 additions & 2 deletions

File tree

web/src/components/ai-elements/code-block.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,13 +508,31 @@ export const CodeBlockCopyButton = ({
508508
const { code } = useContext(CodeBlockContext);
509509

510510
const copyToClipboard = async () => {
511-
if (typeof window === "undefined" || !navigator?.clipboard?.writeText) {
511+
if (typeof window === "undefined") {
512512
onError?.(new Error("Clipboard API not available"));
513513
return;
514514
}
515515

516516
try {
517-
await navigator.clipboard.writeText(code);
517+
if (navigator?.clipboard?.writeText) {
518+
await navigator.clipboard.writeText(code);
519+
} else {
520+
// Fallback for non-secure contexts (HTTP) or older browsers
521+
const textarea = document.createElement("textarea");
522+
textarea.value = code;
523+
textarea.style.position = "fixed";
524+
textarea.style.opacity = "0";
525+
document.body.appendChild(textarea);
526+
try {
527+
textarea.select();
528+
const success = document.execCommand("copy");
529+
if (!success) {
530+
throw new Error("execCommand copy failed");
531+
}
532+
} finally {
533+
document.body.removeChild(textarea);
534+
}
535+
}
518536
setIsCopied(true);
519537
onCopy?.();
520538
setTimeout(() => setIsCopied(false), timeout);

0 commit comments

Comments
 (0)