handle-files-frontendlisted
Install: claude install-skill kennguyen887/agent-foundation
# Handle files in a frontend app
Centralize file work in **one `file.util.ts`** (+ a media/upload service), not ad-hoc per feature.
Examples React/TS; principle → **▸ Example** → **▸ Other stacks**.
## 1. CSV import/export
Export JSON → CSV with a CSV lib (e.g. papaparse `unparse`) + the download helper; import with `parse`.
```ts
export const downloadCsvFromJson = <T>(rows: T[], fileName = 'download') =>
download({ content: unparse(rows), contentType: 'text/csv', fileName });
```
## 2. Download (single + batch zip)
One `download({ content, contentType, fileName })` wrapper over `file-saver`; batch many files into a
zip (`jszip`) for multi-download. "By URL" / "by id" variants resolve the blob, then save.
```ts
await saveMultipleFilesAndZip(files, 'export.zip'); // jszip + file-saver
```
## 3. PDF
View with a PDF component (e.g. react-pdf) — set up the **pdf.js worker once**. Read page count via
pdf.js for validation/pagination: `getPdfPageCountFromUrl(url)`.
## 4. Upload — sniff MIME, presign, resize
- **Detect the real MIME from file CONTENT (magic numbers), not the extension or `file.type`** (both
lie / are spoofable):
```ts
async function detectMimeFromContent(file: File): Promise<string> {
const b = new Uint8Array(await file.slice(0, 12).arrayBuffer());
// match signatures: PNG 89 50 4E 47 · JPEG FF D8 FF · PDF 25 50 44 46 · GIF 47 49 46 · ...
}
```
- **Upload via a presigned URL** — the server signs, the client POSTs the blob straight to stora