Skip to content

Commit 982a456

Browse files
docs: Update clipboard handling for Safari compatibility in LLMButtons (#2258)
https://wolfgangrittner.dev/how-to-use-clipboard-api-in-safari/ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Small, localized change to a UI clipboard action; main risk is browser support/behavior differences for `ClipboardItem` and async fetch failures. > > **Overview** > Updates the `LLMButtons` “Copy for LLM” flow to write fetched Markdown to the clipboard via `navigator.clipboard.write([new ClipboardItem(...)])` instead of `writeText`, avoiding Safari rejecting clipboard operations when the fetch is awaited before the write. > > Adds an in-function debug `console.log` of the created `ClipboardItem`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8ecd7a9. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
1 parent fad13e7 commit 982a456

1 file changed

Lines changed: 14 additions & 10 deletions

File tree

  • apify-docs-theme/src/theme/LLMButtons

apify-docs-theme/src/theme/LLMButtons/index.jsx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,17 +168,21 @@ const onCopyAsMarkdownClick = async ({ setCopyingStatus }) => {
168168
try {
169169
setCopyingStatus('loading');
170170

171-
// Fetch the markdown content
172-
const response = await fetch(markdownUrl);
173-
174-
if (!response.ok) {
175-
throw new Error(`Failed to fetch markdown: ${response.status}`);
176-
}
177-
178-
const markdownContent = await response.text();
171+
// Safari requires clipboard writes to be created synchronously inside the user gesture.
172+
// We therefore pass a Promise that resolves to a Blob into ClipboardItem instead of
173+
// awaiting fetch first — otherwise Safari would reject the clipboard operation.
174+
const markdownContent = new ClipboardItem({
175+
'text/plain': fetch(markdownUrl)
176+
.then((response) => {
177+
if (!response.ok) {
178+
throw new Error(`Failed to fetch markdown: ${response.status}`);
179+
}
180+
return response.text();
181+
})
182+
.then((content) => new Blob([content], { type: 'text/plain' })),
183+
});
179184

180-
// Copy to clipboard
181-
await navigator.clipboard.writeText(markdownContent);
185+
await navigator.clipboard.write([markdownContent]);
182186

183187
// Show success feedback
184188
setCopyingStatus('copied');

0 commit comments

Comments
 (0)