Source Code

<div class="container py-5 d-flex justify-content-center">
  <div class="card bspaste-card">
    <div class="card-body p-4">
      <label class="form-label small fw-semibold">Attach a screenshot</label>
      <div class="bspaste-zone" id="bspasteZone" tabindex="0">
        <div id="bspasteEmpty">
          <p class="mb-1">&#128203;</p>
          <p class="small mb-0">Click here, then press <kbd>Ctrl</kbd>+<kbd>V</kbd> to paste an image</p>
        </div>
        <div class="d-none" id="bspastePreviewWrap">
          <img id="bspastePreview" alt="Pasted image preview">
          <button type="button" class="btn btn-sm btn-outline-danger mt-2" id="bspasteRemove">Remove</button>
        </div>
      </div>
      <p class="small text-muted mt-2 mb-0" id="bspasteStatus">&nbsp;</p>
    </div>
  </div>
</div>

Bootstrap Paste-to-Upload (Clipboard Image Paste) — Free HTML CSS JS Snippet

Bootstrap Paste-to-Upload (Clipboard Image Paste) · Forms · Plain HTML, CSS & JS · Live preview

What's included

Features

Reads a real image directly from the browser's ClipboardEvent, no file picker required
The drop zone is genuinely focusable (tabindex="0"), which is what makes it a valid paste target at all
Explicitly detects and reports clipboard content with no image, instead of failing silently
The previous object URL is revoked before a new one is created, so repeated pastes never leak memory
Remove fully resets the preview and clipboard object URL, ready for another paste immediately

About this UI Snippet

Bootstrap Paste-to-Upload (Clipboard Image Paste) — HTML, CSS & JavaScript

Screenshot of the Bootstrap Paste-to-Upload (Clipboard Image Paste) snippet rendered live

Pasting only works because the drop zone is a real, focusable element — tabindex="0" gives it something a drag-and-drop-only zone lacks: the ability to actually receive keyboard focus, which is a prerequisite for a paste event to ever fire on it at all. Clicking the zone focuses it, and only then does Ctrl+V/Cmd+V dispatch a genuine ClipboardEvent the listener can read from.

The listener reads e.clipboardData.items, finds the first item whose type starts with image/, and calls .getAsFile() to get a real Blob — this correctly ignores a clipboard holding plain copied text (which has no matching item) with an explicit, honest message rather than silently doing nothing or throwing an error.

showImage() revokes any previous object URL with URL.revokeObjectURL(currentUrl) before creating a new one, specifically so pasting a second image doesn't leak the first image's URL — the same object-URL cleanup discipline this collection's bootstrap-image-upload-preview applies per-thumbnail, applied here to a single always-current preview instead of a list.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Hand this snippet to an AI coding assistant like Claude and ask it to also accept a dragged-and-dropped image file on the same zone (combining paste and drag-and-drop into one input method), or to add a max-file-size check with a clear rejection message for an oversized pasted image.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a Bootstrap 5.3 paste-to-upload zone for clipboard images, using the real Bootstrap CDN framework (bootstrap.min.css and bootstrap.bundle.min.js), not custom CSS made to resemble it.

Requirements:
- A dashed-border zone with tabindex="0" so it can receive keyboard focus, showing instructions to click it and press Ctrl+V/Cmd+V.
- Listen for a real "paste" event on the zone, reading e.clipboardData.items to find the first item whose type starts with "image/", and get it as a real Blob via .getAsFile().
- On a successful image paste, show it as a preview using URL.createObjectURL, along with its file size in KB, and reveal a Remove button.
- If the pasted clipboard content contains no image (e.g. plain copied text), show a clear message explaining that instead of doing nothing.
- Revoke the previous object URL before creating a new one on a second paste, and also revoke it when Remove is clicked, so no object URL is ever left un-revoked.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Copy any imageTake a screenshot, or copy an image from another app or webpage, onto your system clipboard.
  2. 2
    Click the dashed paste zone on this pageIt visually focuses with a highlighted border, ready to receive a paste.
  3. 3
    Press Ctrl+V (or Cmd+V on Mac)The pasted image appears as a preview immediately, along with its size in KB.
  4. 4
    Try pasting plain copied text insteadA clear message explains no image was found, rather than doing nothing silently.
  5. 5
    Click "Remove"The preview clears, its object URL is released, and the zone returns to its empty, focused state ready for another paste.

Real-world uses

Common Use Cases

DEV
Bug report and support ticket forms
Pasting a screenshot directly is dramatically faster than saving it to disk first and browsing to it — pairs with bootstrap-file-upload-drag-drop as an alternate input method.
Design feedback and annotation tools
A natural fit anywhere a user is likely to already have a screenshot on their clipboard mid-workflow.
Chat and comment boxes accepting image attachments
Lets a user paste an image straight into a message the same way many chat apps already support.

Got questions?

Frequently Asked Questions

Only a focused, focusable element receives a paste event through the standard clipboard shortcut — without tabindex, a plain div can never gain keyboard focus, so Ctrl+V would have nowhere to dispatch its ClipboardEvent to.

The items array is searched for an entry whose type starts with "image/"; when none is found, the zone shows an explicit "no image found" message instead of silently ignoring the paste or throwing an error.

Clipboard paste support for images varies significantly across mobile browsers and is generally less reliable than on desktop — a real implementation should keep a traditional file input available as a fallback on touch devices.

Yes. Attach the paste listener to a ref'd element in a mount hook, store the object URL in component state (revoking the previous one in the same setter, e.g. inside a state updater callback), and clean up on unmount to avoid a leaked URL if the component unmounts mid-preview.