Skip to content

Commit 129dd40

Browse files
Parkreinerbpmct
authored andcommitted
fix: improve clipboard support on HTTP connections and older browsers (#12178)
* fix: add future-proofing for clipboard copies on http connections * docs: clean up comment formatting
1 parent d448c49 commit 129dd40

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

site/src/hooks/useClipboard.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const useClipboard = (textToCopy: string): UseClipboardResult => {
2222
setIsCopied(false);
2323
}, 1000);
2424
} catch (err) {
25-
const isCopied = simulateClipboardWrite();
25+
const isCopied = simulateClipboardWrite(textToCopy);
2626
if (isCopied) {
2727
setIsCopied(true);
2828
timeoutIdRef.current = window.setTimeout(() => {
@@ -44,12 +44,16 @@ export const useClipboard = (textToCopy: string): UseClipboardResult => {
4444
};
4545

4646
/**
47+
* Provides a fallback clipboard method for when browsers do not have access
48+
* to the clipboard API (the browser is older, or the deployment is only running
49+
* on HTTP, when the clipboard API is only available in secure contexts).
50+
*
4751
* It feels silly that you have to make a whole dummy input just to simulate a
4852
* clipboard, but that's really the recommended approach for older browsers.
4953
*
5054
* @see {@link https://web.dev/patterns/clipboard/copy-text?hl=en}
5155
*/
52-
function simulateClipboardWrite(): boolean {
56+
function simulateClipboardWrite(textToCopy: string): boolean {
5357
const previousFocusTarget = document.activeElement;
5458
const dummyInput = document.createElement("input");
5559

@@ -70,12 +74,26 @@ function simulateClipboardWrite(): boolean {
7074
style.border = "0";
7175

7276
document.body.appendChild(dummyInput);
77+
dummyInput.value = textToCopy;
7378
dummyInput.focus();
7479
dummyInput.select();
7580

76-
const isCopied = document.execCommand("copy");
77-
dummyInput.remove();
81+
/**
82+
* The document.execCommand method is officially deprecated. Browsers are free
83+
* to remove the method entirely or choose to turn it into a no-op function
84+
* that always returns false. You cannot make any assumptions about how its
85+
* core functionality will be removed.
86+
*
87+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Clipboard}
88+
*/
89+
let isCopied: boolean;
90+
try {
91+
isCopied = document?.execCommand("copy") ?? false;
92+
} catch {
93+
isCopied = false;
94+
}
7895

96+
dummyInput.remove();
7997
if (previousFocusTarget instanceof HTMLElement) {
8098
previousFocusTarget.focus();
8199
}

0 commit comments

Comments
 (0)