onmyway133 / blog

🍁 What you don't know is what you haven't learned
https://onmyway133.com/
MIT License
669 stars 33 forks source link

How to read image paste from clipboard in React #968

Open onmyway133 opened 5 months ago

onmyway133 commented 5 months ago

Are you looking to grab images directly from your clipboard with a button click on your web page? The Async Clipboard API makes this quite easy and efficient. Let's break it down into simpler steps:

Requesting Permission

The first time you try to read something from the clipboard using this method, your browser will ask for permission. This is a security feature to ensure that websites don't access your clipboard without your consent.

Reading from Clipboard

Once permission is granted, the code will check the clipboard for images. This is done using a method called read() from the Clipboard API.

To show this image on the webpage, we convert this blob into something the browser can display. We do this using URL.createObjectURL(blob), which creates a URL for the blob. Then, we can simply set this URL as the source of an image tag ().

For image data, the imageTypes can be image/png

import React, { useState } from 'react';

function MyComponent() {
  const [imageSrc, setImageSrc] = useState('');

  const handlePaste = async (event) => {
    try {
      if (!navigator.clipboard) {
        console.error("Clipboard API not available");
        return;
      }

      const clipboardItems = await navigator.clipboard.read();
      for (const clipboardItem of clipboardItems) {
        const imageTypes = clipboardItem.types.find(type => type.startsWith('image/'));

        if (imageTypes) {
          const blob = await clipboardItem.getType(imageTypes);
          const url = URL.createObjectURL(blob);
          setImageSrc(url);
          break; // Assuming we need the first image
        }
      }
    } catch (err) {
      console.error("Failed to read clipboard:", err);
    }
  };

  return (
    <div>
      <div
        onPaste={handlePaste}
      >
        Paste an image here
      </div>
      {imageSrc && <img src={imageSrc} alt="Pasted" />}
    </div>
  );
}

export default MyComponent;