Web APIs Cheatsheet

Clipboard and File API

Use this Web APIs reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Clipboard API (Async)

Requires HTTPS and clipboard-read/clipboard-write permissions.

// Write text
await navigator.clipboard.writeText('Hello, clipboard!');

// Read text
const text = await navigator.clipboard.readText();

// Write multiple items / rich content
await navigator.clipboard.write([
  new ClipboardItem({
    'text/plain': new Blob(['plain text'], { type: 'text/plain' }),
    'text/html': new Blob(['<b>bold</b>'], { type: 'text/html' }),
    'image/png': imageBlob,
  }),
]);

// Read clipboard items
const items = await navigator.clipboard.read();
for (const item of items) {
  item.types;                           // ['text/plain', 'image/png']
  if (item.types.includes('image/png')) {
    const blob = await item.getType('image/png');
    const url = URL.createObjectURL(blob);
  }
}

Permission Check

const write = await navigator.permissions.query({ name: 'clipboard-write' });
const read  = await navigator.permissions.query({ name: 'clipboard-read' });
write.state; // 'granted' | 'denied' | 'prompt'

Clipboard Events (Legacy)

// copy — fires on Ctrl+C / Cmd+C
document.addEventListener('copy', e => {
  const selection = window.getSelection()?.toString();
  e.clipboardData.setData('text/plain', selection + '\n— example.com');
  e.clipboardData.setData('text/html', `<p>${selection}</p>`);
  e.preventDefault(); // suppress default copy
});

// cut
document.addEventListener('cut', e => {
  e.clipboardData.setData('text/plain', selectedText);
  deleteSelection();
  e.preventDefault();
});

// paste
document.addEventListener('paste', e => {
  const text = e.clipboardData.getData('text/plain');
  const html  = e.clipboardData.getData('text/html');
  // Files pasted from OS
  const files = [...e.clipboardData.files];
  e.preventDefault();
});

ClipboardEvent.clipboardData Methods

MethodDescription
.getData(type)Returns string for the given MIME type
.setData(type, data)Set data for MIME type (only inside copy/cut handler)
.clearData(type?)Clear one or all types
.filesFileList of pasted files
.itemsDataTransferItemList
.typesArray of available MIME type strings

DataTransfer and DataTransferItem

// Also used in drag events (e.dataTransfer)
const dt = e.clipboardData; // DataTransfer

for (const item of dt.items) {
  item.kind;    // 'string' | 'file'
  item.type;    // MIME type string

  if (item.kind === 'string') {
    item.getAsString(str => console.log(str));
  }
  if (item.kind === 'file') {
    const file = item.getAsFile(); // File object
  }
}

File API

File and Blob

Property / MethodTypeDescription
file.namestringOriginal filename
file.sizenumberSize in bytes
file.typestringMIME type (empty if unknown)
file.lastModifiednumberms since epoch
file.lastModifiedDateDateDeprecated
file.text()Promise\<string\>Read as UTF-8 text
file.arrayBuffer()Promise\<ArrayBuffer\>Read as binary
file.stream()ReadableStreamStreaming read
file.slice(start?, end?, type?)BlobSlice a byte range
// File inherits from Blob
const blob = new Blob(['hello'], { type: 'text/plain' });
const file = new File([blob, ' world'], 'hello.txt', { type: 'text/plain', lastModified: Date.now() });

// Slice large files for chunked upload
function* chunkFile(file, chunkSize = 1024 * 1024) {
  let offset = 0;
  while (offset < file.size) {
    yield file.slice(offset, offset + chunkSize);
    offset += chunkSize;
  }
}

FileReader (event-based, legacy)

const reader = new FileReader();

reader.readAsText(file, 'utf-8');
reader.readAsDataURL(file);          // base64 data: URL
reader.readAsArrayBuffer(file);
reader.readAsBinaryString(file);     // Deprecated

reader.onload = e => {
  e.target.result;  // string | ArrayBuffer
};
reader.onprogress = e => {
  e.loaded; e.total; e.lengthComputable;
};
reader.onerror = e => e.target.error;  // DOMException
reader.onabort = e => {};
reader.abort();

reader.readyState; // 0=EMPTY, 1=LOADING, 2=DONE
reader.result;     // after load: string | ArrayBuffer | null

Modern File Reading (Promise-based)

// Prefer these over FileReader
const text   = await file.text();
const buffer = await file.arrayBuffer();
const stream = file.stream();          // ReadableStream<Uint8Array>

// Stream processing
const reader = file.stream().getReader();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  process(value); // Uint8Array chunk
}

Object URLs

const url = URL.createObjectURL(file);  // blob:... URL, in-memory
img.src = url;                          // use immediately

// IMPORTANT: release when done to free memory
URL.revokeObjectURL(url);

// Revoke after load
img.onload = () => URL.revokeObjectURL(url);

File System Access API (modern, browser-only)

Open Files

// Single file
const [handle] = await window.showOpenFilePicker({
  multiple: false,
  types: [{ description: 'Images', accept: { 'image/*': ['.png', '.jpg', '.webp'] } }],
  excludeAcceptAllOption: false,
  startIn: 'pictures', // 'desktop' | 'documents' | 'downloads' | 'music' | 'pictures' | 'videos'
});

const file = await handle.getFile();
const text = await file.text();

// Multiple files
const handles = await window.showOpenFilePicker({ multiple: true });

Save Files

const handle = await window.showSaveFilePicker({
  suggestedName: 'data.json',
  types: [{ description: 'JSON', accept: { 'application/json': ['.json'] } }],
});

const writable = await handle.createWritable();
await writable.write('{"hello": "world"}');
await writable.write(new Blob([data]));
await writable.write({ type: 'write', data, position: 0 });  // write at offset
await writable.write({ type: 'seek', position: 10 });         // seek
await writable.write({ type: 'truncate', size: 100 });        // resize
await writable.close();

Directory Picker

const dirHandle = await window.showDirectoryPicker({
  id: 'project-folder',
  mode: 'readwrite', // 'read' | 'readwrite'
});

// List files
for await (const [name, handle] of dirHandle) {
  handle.kind; // 'file' | 'directory'
  handle.name;
}

// Get file in directory
const fileHandle = await dirHandle.getFileHandle('README.md');
const subDir     = await dirHandle.getDirectoryHandle('src', { create: true });
await dirHandle.removeEntry('old-file.txt', { recursive: false });

// File handle methods
handle.kind;   // 'file'
handle.name;   // 'README.md'
await handle.isSameEntry(otherHandle);
await handle.queryPermission({ mode: 'readwrite' }); // 'granted' | 'denied' | 'prompt'
await handle.requestPermission({ mode: 'readwrite' });

Persist Handle Across Sessions (with IndexedDB)

// Store handle in IDB — permissions may need re-requesting on next visit
import { set, get } from 'idb-keyval';
await set('last-file', fileHandle);
const restored = await get('last-file');
// Re-request permission
if (await restored.queryPermission({ mode: 'readwrite' }) !== 'granted') {
  await restored.requestPermission({ mode: 'readwrite' });
}

File Input Programmatic Tricks

const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/*';
input.multiple = true;
input.addEventListener('change', () => {
  const files = [...input.files];
});
input.click(); // trigger picker without user clicking an element

// Drag-and-drop file entry
dropZone.addEventListener('drop', async e => {
  e.preventDefault();
  for (const item of e.dataTransfer.items) {
    if (item.kind === 'file') {
      const file = item.getAsFile();
      // or FileSystem API entry
      const entry = item.webkitGetAsEntry();
      if (entry.isDirectory) readDir(entry);
    }
  }
});