Skip to content

Commit b1a52f2

Browse files
boojackclaude
andcommitted
fix(web): add clipboard fallback for CodeBlock copy button in non-secure contexts
The CodeBlock component was refactored in v0.25.3 to use navigator.clipboard.writeText(), which requires HTTPS or localhost. This caused the copy button to fail silently for users accessing Memos over HTTP. This fix adds a fallback to the copy-to-clipboard library (already used by all other copy operations in the codebase) when the native clipboard API is unavailable or fails, ensuring the copy button works reliably in all deployment scenarios. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent a2ddf05 commit b1a52f2

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

web/src/components/MemoContent/CodeBlock.tsx

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import copy from "copy-to-clipboard";
12
import hljs from "highlight.js";
23
import { CheckIcon, CopyIcon } from "lucide-react";
34
import { observer } from "mobx-react-lite";
@@ -82,11 +83,31 @@ export const CodeBlock = observer(({ children, className, ...props }: CodeBlockP
8283

8384
const handleCopy = async () => {
8485
try {
85-
await navigator.clipboard.writeText(codeContent);
86-
setCopied(true);
87-
setTimeout(() => setCopied(false), 2000);
86+
// Try native clipboard API first (requires HTTPS or localhost)
87+
if (navigator.clipboard && window.isSecureContext) {
88+
await navigator.clipboard.writeText(codeContent);
89+
setCopied(true);
90+
setTimeout(() => setCopied(false), 2000);
91+
} else {
92+
// Fallback to copy-to-clipboard library for non-secure contexts
93+
const success = copy(codeContent);
94+
if (success) {
95+
setCopied(true);
96+
setTimeout(() => setCopied(false), 2000);
97+
} else {
98+
console.error("Failed to copy code");
99+
}
100+
}
88101
} catch (err) {
89-
console.error("Failed to copy code:", err);
102+
// If native API fails, try fallback
103+
console.warn("Native clipboard failed, using fallback:", err);
104+
const success = copy(codeContent);
105+
if (success) {
106+
setCopied(true);
107+
setTimeout(() => setCopied(false), 2000);
108+
} else {
109+
console.error("Failed to copy code:", err);
110+
}
90111
}
91112
};
92113

0 commit comments

Comments
 (0)