AykutSarac/jsoncrack.com · error

Clipboard write permission denied. Please allow clipboard ac

Error message

Clipboard write permission denied. Please allow clipboard access in your browser settings.

What it means

Toast shown when navigator.clipboard.write rejects with a DOMException whose name is 'NotAllowedError'. This is the Permissions API path: the browser blocked clipboard write because the document is not in a secure context (HTTPS/localhost), the user denied the permission, or the call did not occur during a user gesture. The error is matched explicitly via error.name.

Source

Thrown at apps/www/src/features/modals/DownloadModal/index.tsx:106

        backgroundColor: fileDetails.backgroundColor,
        skipFonts: true,
      };

      const blob = await toBlob(imageElement, imageOptions);

      if (!blob) return;

      await navigator.clipboard?.write([
        new ClipboardItem({
          [blob.type]: blob,
        }),
      ]);

      toast.success("Copied to clipboard");
      gaEvent("clipboard_img");
    } catch (error) {
      if (error instanceof Error && error.name === "NotAllowedError") {
        toast.error(
          "Clipboard write permission denied. Please allow clipboard access in your browser settings."
        );
      } else {
        toast.error("Failed to copy to clipboard");
      }
    } finally {
      toast.dismiss("toastClipboard");
      onClose();
    }
  };

  const exportAsImage = async () => {
    try {
      toast.loading("Downloading...", { id: "toastDownload" });

      const imageElement = getExportElement();
      if (!imageElement) {
        toast.error("Canvas not found.");

View on GitHub (pinned to 3c9af69e23)

Solutions

  1. Serve the app over HTTPS (or localhost) so the async Clipboard API is available.
  2. Ensure the export is triggered from a user gesture (click handler).
  3. Add `allow="clipboard-write"` to any embedding iframe.
  4. Fall back to document.execCommand('copy') or a download link when NotAllowedError occurs.

Example fix

// before
await navigator.clipboard?.write([new ClipboardItem({ [blob.type]: blob })]);

// after — fall back to a download when clipboard permission is denied
try {
  await navigator.clipboard?.write([new ClipboardItem({ [blob.type]: blob })]);
  toast.success("Copied to clipboard");
} catch (error) {
  if (error instanceof DOMException && error.name === "NotAllowedError") {
    downloadURI(URL.createObjectURL(blob), `${fileDetails.filename}.png`);
    toast("Clipboard blocked — downloaded instead.");
  } else {
    throw error;
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Verify secure context + clipboard permission before offering copy
export function canWriteClipboard(): boolean {
  return typeof window !== "undefined"
    && window.isSecureContext
    && !!navigator.clipboard
    && typeof ClipboardItem !== "undefined";
}

Type guard

// Identify the permission-denied DOMException
export function isClipboardDenied(error: unknown): error is DOMException {
  return error instanceof DOMException && error.name === "NotAllowedError";
}

Try / catch

// Match NotAllowedError explicitly, fall back otherwise
if (isClipboardDenied(error)) {
  toast.error("Clipboard write permission denied. Allow clipboard access.");
} else {
  // fall back to download
}

Prevention

When it happens

Trigger: Site served over HTTP (not a secure context); clipboard permission denied in browser settings; the ClipboardItem write was triggered programmatically outside a user activation; running inside an iframe without the `clipboard-write` permission policy.

Common situations: Local development over plain IP/HTTP; embedding the app in a sandboxed iframe; browser privacy settings blocking clipboard; programmatic (non-click) export attempts.

Related errors


AI-assisted analysis of AykutSarac/jsoncrack.com@3c9af69e23 (2026-08-12). Data as JSON: /api/errors/14973d305ad06b9a. Report an issue: GitHub.