Raycast Clipboard API: Read Text Without Losing HTML

Published on
Written by
Pastea Team
Reading time
4 min read

If your Raycast extension reads a rich copy as text and writes that string back, the result is a text copy. The original styling does not travel with the string.

Use Clipboard.read() when you need to inspect the available HTML as well as text. Use Clipboard.readText() when plain text is the intended input. Preserving HTML can preserve some rich content, but neither operation is a universal clone of every format on the Mac pasteboard.

Here is how to make that distinction explicit in an extension.

“Keep the formatting” can mean several things:

Intended resultDesign choice
Process a command, identifier, or URLRead and write plain text deliberately
Forward rich text when HTML is availableRead HTML and retain a text fallback
Preserve arbitrary app-specific clipboard dataDo not assume an HTML/text round trip can do it
Convert content into MarkdownTreat it as a conversion with different output

For example, a command that normalizes a ticket number has no reason to keep a webpage's font. A command that forwards a styled support reply may have a reason to retain its links and emphasis.

Define that behavior before choosing the API. Otherwise a convenient string operation becomes an accidental format conversion.

Raycast's Clipboard API reference documents read, readText, and copying HTML with an optional text representation. Read a snapshot, inspect the fields, and decide which output you can support.

This illustrative no-view command retains supplied HTML when available and falls back to supplied text. It reports a fixed error instead of logging clipboard contents:

import { Clipboard, showToast, Toast } from "@raycast/api";

export default async function Command() {
  try {
    const copied = await Clipboard.read();
    const html = "html" in copied ? copied.html : undefined;
    const text = "text" in copied ? copied.text : undefined;

    if (typeof html === "string" && html.length > 0) {
      await Clipboard.copy({
        html,
        ...(typeof text === "string" ? { text } : {}),
      });
    } else if (typeof text === "string") {
      await Clipboard.copy(text);
    } else {
      await showToast({
        style: Toast.Style.Failure,
        title: "This command supports text and HTML only",
      });
      return;
    }

    await showToast({
      style: Toast.Style.Success,
      title: "Supported content copied",
    });
  } catch {
    await showToast({
      style: Toast.Style.Failure,
      title: "Could not copy supported content",
    });
  }
}

The command copies its result back to the clipboard. It does not paste into another application. That separation makes it easier to inspect the result before inserting it somewhere important. Raycast documents toast behavior separately in its feedback API.

The guards also make the unsupported case visible. This example does not claim to handle images or file copies.

A clipboard entry can offer several representations of the same selection. A receiving application chooses a representation it understands. Apple's pasteboard documentation describes this exchange between applications.

Consider a copied link whose visible text is “Read the setup guide.” The text representation may contain those words. The HTML representation may also contain the destination URL and emphasis. Writing only the visible words cannot retain a link destination that was never included in your output.

The loss can happen at several points:

Check each boundary. More complicated copying code cannot invent formatting the source did not provide.

An application may use RTF, image data, multiple items, or its own private representation. Retaining HTML does not establish that those other representations survived.

Even valid HTML may render differently in two editors. A destination can reinterpret paragraph spacing, reject styles, replace fonts, or accept only text. If exact visual appearance matters, a document or image may be a better transfer format than an editable text paste.

There is also a difference between the built-in Raycast history command and an extension's public API. A history feature supporting original formats does not mean every representation is exposed through the extension method you called. Our Raycast history guide covers the user-facing workflow.

The API reference documents an offset from 0 through 5 for reading recent history. That is a bounded access mechanism, not a documented full-history search API.

Do not build a loop that assumes arbitrary offsets will enumerate everything a user has saved. If your feature needs “the last few copies,” that limit may fit. If it needs semantic search across months of clips, design for a source that explicitly supports that task.

For a different integration model, Pastea exposes approved clipboard access to compatible coding tools through MCP. Our clipboard-to-AI guide explains that workflow and its access controls. It does not extend Raycast's API or make these methods interchangeable.

Before shipping a format-sensitive command, try this small matrix with harmless sample content:

InputWhat to inspect
Plain paragraphCharacters and line breaks survive
Bold text with a hyperlinkEmphasis and the actual link destination survive where supported
Table copied from a documentCells remain useful, or the unsupported behavior is explained
Image or Finder fileThe command reports its text/HTML limitation
Rich copy pasted into a plain-text editorText remains usable without promising styling

These are validation cases, not measured compatibility results. Test the actual source, destination, Raycast version, and operating system you support.

An open report in Raycast's repository describes missing HTML in a Windows clipboard round trip. It is a platform-specific report, not evidence that the same bug affects Mac. It is a useful reason to verify behavior instead of treating a type signature as a compatibility test.

For ordinary Mac use, see how to paste with formatting. For extension authors, the rule is more specific: preserve the representations your command supports, describe the rest honestly, and never log a user's copied material just to find out what format it had.