Source Code

<div class="container py-5 d-flex justify-content-center">
  <div class="card bsdupe-card">
    <div class="card-body p-4">
      <label class="form-label small fw-semibold">Attach files</label>
      <input type="file" class="form-control mb-2" id="bsdupeInput" multiple>
      <p class="small mb-3 d-none" id="bsdupeWarning"></p>
      <ul class="list-unstyled mb-0" id="bsdupeList"></ul>
    </div>
  </div>
</div>

Bootstrap Duplicate File Detection on Upload — Free HTML CSS JS Snippet

Bootstrap Duplicate File Detection on Upload · Forms · Plain HTML, CSS & JS · Live preview

What's included

Features

Duplicates are matched on name, size, and last-modified time together, not name alone
A newly accepted file is immediately added to the comparison set, catching duplicates within the same selection
The warning names the exact files that were skipped, not a generic duplicate message
The warning only appears when a real duplicate was caught, hidden otherwise
The file input resets after every selection so choosing the same file again is always possible to test

About this UI Snippet

Bootstrap Duplicate File Detection on Upload — HTML, CSS & JavaScript

Screenshot of the Bootstrap Duplicate File Detection on Upload snippet rendered live

Detecting a true duplicate needs a signature that's cheap to compute but specific enough to trust — signature() combines a file's name, size, and lastModified timestamp into one string, since two genuinely different files sharing all three values at once is vanishingly unlikely, while hashing every byte of every file just to compare them would be needless work for a client-side check like this one.

Every incoming file is checked against a Set built from every file already added, and — this is the detail that's easy to get wrong — newly accepted files are added to that same existingSignatures Set as they're processed, not only checked against the pre-existing list. Without that, selecting the identical file twice within a single multi-select dialog (dragging the same file into the selection twice, which some file pickers allow) would let both copies through, since neither would exist in the list yet at comparison time.

The warning message is built from an actual list of the skipped file names, not a generic "duplicate detected" — duplicates.push(file.name) collects every skipped file across the current selection so a user attaching ten files at once, three of which were already added, sees exactly which three were rejected rather than being left to guess.

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 add a real content-hash check (using the SubtleCrypto API to hash each file's bytes) for cases where name/size/lastModified matching isn't strict enough, or to add a "Replace existing" option letting a user intentionally re-add a file that overwrites the previous one instead of being silently skipped.

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 file input with duplicate detection, using the real Bootstrap CDN framework (bootstrap.min.css and bootstrap.bundle.min.js), not custom CSS made to resemble it.

Requirements:
- A multiple file input that maintains a running list of attached files, rendered below it with each file's name and size.
- Build a signature for each file from its name, size, and lastModified timestamp combined, and use it to detect whether an incoming file has already been added.
- A newly accepted file must be added to the set used for duplicate comparison immediately, so that selecting the same file twice within a single multi-file selection dialog is also caught, not just across separate selections.
- When one or more duplicates are caught in a selection, show a warning message naming exactly which file names were skipped, and hide the warning entirely when a selection contains no duplicates.
- Reset the file input's value after every change so the same file can be re-selected to test the duplicate detection again.

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
    Select a fileIt's added to the list below with its size shown.
  2. 2
    Open the file picker again and select the exact same fileA warning appears reading "Skipped duplicate: [filename]" — it isn't added a second time.
  3. 3
    Select a mix of new and already-added files at onceThe new ones are added normally, and the warning lists only the ones that were actually duplicates.
  4. 4
    Select only genuinely new filesNo warning appears at all — the message only shows when a real duplicate was caught.

Real-world uses

Common Use Cases

Document and attachment upload forms
Prevents an accidentally doubled attachment, especially when a form allows adding files across several separate selections.
Bulk import and data-loading tools
Catches an operator re-selecting a file they already queued for import earlier in the same session.
Learning cheap-but-effective duplicate detection
A realistic example of when a lightweight signature is the right tool instead of reaching for full content hashing.

Got questions?

Frequently Asked Questions

No — it compares name, size, and last-modified timestamp together, which correctly catches the overwhelmingly common real case (re-selecting the same file) without the cost of reading and hashing every byte of every file client-side.

It's theoretically possible for two unrelated files to share an identical name, byte size, and modification timestamp down to the millisecond, but in practice this is extremely unlikely for files someone is deliberately attaching to the same form.

It's still caught — each file in the current selection is added to the comparison Set as it's processed, so the second occurrence in the same batch is checked against the first one already added moments earlier.

Yes. Keep the added files array in component state, and run the same signature-based Set comparison inside your change handler before merging new files into that state — no other logic needs to change.