Validate a Multi-File Upload Action
Hard · Server Actions
A form like <form action={upload}><input type="file" name="files" multiple /></form> sends a FormData to a Server Action. Every chosen file becomes a File entry under the same key, so you read them with formData.getAll("files"). Never trust the browser: sizes, types and file names must be checked on the server.
The options are bound to the action (uploadFiles.bind(null, options)), so it receives (options, formData). Write uploadFiles and return { ok, errors, files }:
- Keep only File entries of files with a size above 0 (when nothing is chosen, browsers send one empty file with no name). Strings under the same key are ignored.
- Request-level checks, in this order; the first failing one returns { ok: false, errors: [message], files: [] }: no files gives Choose at least one file; more than maxFiles gives You can upload at most 3 files; a total size above maxTotalBytes gives Total size must be at most 250 bytes (always with the real numbers).
- Otherwise one result per file, in order: { name, size, type, ok }, plus error only when it failed: Unsupported file type when type is not in allowedTypes, else File is too large when size > maxBytes.
- name is sanitized: keep only the part after the last / or \ (Windows paths like C:\fakepath\cat.png), replace every run of characters other than letters, digits, ., _ and - with one _, then remove leading dots. If nothing is left, use file.
- If a name was already used by an earlier result, add -1, -2, … before the extension (the part from the last ., if it is not the first character): cat.png, cat-1.png, cat-2.png.
- ok is true when every file is ok.