From 390d021d0ad7b88128675cadf8787c55264287c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Biro=C5=A1?= Date: Tue, 17 Feb 2026 13:39:02 +0100 Subject: [PATCH] fix: Improve clipboard handling for Safari in `LLMButtons` component --- website/src/components/LLMButtons.jsx | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/website/src/components/LLMButtons.jsx b/website/src/components/LLMButtons.jsx index 80f36442ec..3e9a0632af 100644 --- a/website/src/components/LLMButtons.jsx +++ b/website/src/components/LLMButtons.jsx @@ -311,14 +311,23 @@ const onCopyAsMarkdownClick = async ({ setCopyingStatus, currentUrl }) => { try { setCopyingStatus('loading'); - const response = await fetch(markdownUrl); + // Safari requires clipboard writes to be created synchronously inside the user gesture. + // We therefore pass a Promise that resolves to a Blob into ClipboardItem instead of + // awaiting fetch first — otherwise Safari would reject the clipboard operation. + const markdownContent = new ClipboardItem({ + 'text/plain': fetch(markdownUrl) + .then((response) => { + if (!response.ok) { + throw new Error(`Failed to fetch markdown: ${response.status}`); + } + return response.text(); + }) + .then((content) => new Blob([content], { type: 'text/plain' })), + }); - if (!response.ok) { - throw new Error(`Failed to fetch markdown: ${response.status}`); - } + await navigator.clipboard.write([markdownContent]); - const markdownContent = await response.text(); - await navigator.clipboard.writeText(markdownContent); + // Show success feedback setCopyingStatus('copied'); } catch (error) { console.error('Failed to copy markdown content:', error);