# React File Manager: Ordner, Uploads und die Backend-API

> So baust du einen React File Manager für SaaS-Dokumente: Ordner im Raster oder als Liste, ein Ordnerbaum, Uploads, Massenaktionen und die API dahinter.

- Autor: [Serban Rusu](https://wingo-ui.com/blog/authors/serban), Founder of Wingo UI
- Veröffentlicht: 6. Nov. 2026
- Kategorie: [Komponenten-Guides](https://wingo-ui.com/de/blog/category/components)
- Lesezeit: 10 Min.
- Kanonische URL: https://wingo-ui.com/de/blog/react-file-manager
- Englische Fassung: https://wingo-ui.com/blog/react-file-manager

## Kurz gesagt

Ein React File Manager für ein SaaS braucht Ordner im Raster und als Liste, einen Ordnerbaum und eine Breadcrumb, Uploads mit Fortschritt, Verschieben und Löschen in Massen, Tastaturbedienung und ein Layout fürs Smartphone; die meiste Arbeit steckt aber im Backend-Vertrag dahinter. Modellier den Baum als flache Zeilen mit id und parentId, lade über Presigned URLs direkt in den Storage hoch und lass den Server Verschiebungen ablehnen, die einen Ordner in sich selbst legen würden. Nimm einen Dokumentenmanager für die Dateien einer Firma oder eines Datensatzes und einen File Browser im Finder-Stil, wenn Leute ein großes Laufwerk durchstöbern und Dateien in der Vorschau ansehen.

Jedes SaaS, das Dokumente speichert, bekommt früher oder später einen Tab „Dateien“: Verträge an einem Kundendatensatz, Rechnungen pro Monat, Fotos von einem Vor-Ort-Termin. Ein React File Manager sieht aus wie ein Raster aus Icons, aber die Arbeit steckt woanders: in verschachtelten Ordnern, in Uploads, die auf halber Strecke abbrechen, in 40 ausgewählten Dateien, die jemand in einen anderen Ordner zieht, und darin, dass auf dem Smartphone nichts davon an Hover oder Rechtsklick hängen darf. Dieser Guide zeigt, was ein React Dateimanager können muss, wann ein File Browser im Finder-Stil besser passt, welchen Backend-Vertrag beide brauchen und welche Open-Source-Optionen es gibt. Die Beispiele nutzen die Komponenten [File Manager](https://wingo-ui.com/components/file-manager) und [File System](https://wingo-ui.com/components/file-system) von Wingo UI, der Bibliothek, die wir bauen. Wir sind also nicht neutral; Fakten zu anderen Projekten verlinken auf ihre Quellen.

## Was muss ein React File Manager in einer SaaS-App können?

Gegen diese Liste haben wir unsere React File Manager UI gebaut. Sie ist auch ein fairer Test für jedes Paket und für eine selbst geschriebene Version:

- **Ordner in zwei Layouts.** Ein Raster mit Vorschaubildern für Fotos und eine Liste mit den Spalten Modified, Size und Owner für Dokumente, dazu ein Umschalter, der sich die Wahl merkt.
- **Wo bin ich.** Eine Breadcrumb, deren Einträge Drop-Ziele sind, und ein Ordnerbaum neben den Dateien, wenn Platz dafür ist.
- **Auswahl und Massenaktionen.** Klick, Cmd oder Strg + Klick, Shift + Klick für einen Bereich, eine Checkbox pro Element und eine Toolbar, die Verschieben, Herunterladen und Löschen anbietet, sobald etwas ausgewählt ist.
- **Uploads.** Ein Button, Drag and Drop vom Desktop in den offenen Ordner oder auf eine Ordnerkachel, Einfügen aus der Zwischenablage, eine Fortschrittszeile pro Datei und abgelehnte Dateien mit Begründung.
- **Umbenennen, verschieben, löschen.** Umbenennen direkt an Ort und Stelle mit einem Fehler unter dem Feld, wenn der Server ablehnt, Verschieben per Drag oder Dialog, Löschen mit einer Bestätigung, die nennt, was verschwindet.
- **Suche über alle Ordner**, mit dem Ordnerpfad zu jedem Treffer.
- **Tastatur und Touch.** Pfeiltasten, Enter, Entf, F2 und Backspace am Desktop; Tippen, langes Drücken und Bottom Sheets auf dem Smartphone.

Installier die Komponente:

```bash
npx wingo-ui@latest add file-manager
```

Sie bringt ihre Teile mit (Tree View, File Upload, Breadcrumb, Kontextmenü, Lightbox und Dialoge), denn eine File Manager UI setzt sich genau aus diesen Teilen zusammen. Probier die Demo unten aus: Sie hält die Dateien im Speicher, du kannst also beliebig hochladen, umbenennen, verschieben und löschen.

> Live-Demo (File manager): Wähl zwei Dateien mit Cmd oder Strg + Klick aus und zieh sie auf eine Ordnerkachel oder einen Eintrag in der Breadcrumb, dann drück F2 auf einer Datei, um sie direkt umzubenennen. Probier sie unter [File manager](https://wingo-ui.com/components/file-manager) aus und installier sie mit `npx wingo-ui@latest add file-manager`.

## File Manager oder File Browser im Finder-Stil: Was brauchst du?

Nimm einen File Manager, wenn die Dateien zu einem Datensatz gehören und Leute kommen, um eine Datei abzulegen oder zu holen. Nimm einen File Browser im Finder-Stil, wenn die Dateien selbst der Inhalt der Seite sind: Leute verbringen Zeit darin, wechseln zwischen vielen Ordnern und wollen in Dateien hineinschauen, ohne sie herunterzuladen. Wingo UI hat für jede Form eine Komponente: File Manager für die erste und File System, eine React File Browser Komponente im Finder-Stil, für die zweite.

| | File Manager (`file-manager`) | File System (`file-system`) |
|---|---|---|
| Typischer Ort | Ein Tab „Dokumente“ an einem Datensatz oder einer Firma | Ein eigener Screen für ein Laufwerk oder eine Mediathek |
| Ansichten | Raster und Liste | Symbole, Liste, Spalten und Galerie |
| Navigation | Breadcrumb, Ordnerbaum, Suche | Seitenleiste mit Favoriten, Orten und Tags, Zurück und Vor, Pfadleiste, Palette „Gehe zu“ |
| Vorschauen | Bilder in einer Lightbox | Quick Look für PDF, Word, Excel, CSV, PowerPoint, Bilder, Video, Audio, Markdown, Code |
| Daten | Flache Elemente mit parentId | Verschachtelte children, flache parentId oder lazy `loadChildren` pro Ordner |
| Extras | Speicherplatzanzeige, Upload-Panel, Spalte für den Besitzer | Kopieren und Duplizieren, Tags, Informationen, ein Ordner mit 10.000 Dateien bleibt virtualisiert |

Unsere Faustregel: ein File Manager für „die Dateien, die zu dieser Sache gehören“, ein File Browser für „einen Ort, an dem Dateien leben“. Wenn Leute vor allem hoch- und herunterladen, machen die zusätzlichen Ansichten des Browsers die Seite nur schwerer.

> Live-Demo (File System): Drück die Leertaste auf einer Datei, um Quick Look zu öffnen, und wechsle dann mit Cmd oder Strg + 3 zur Spaltenansicht. Probier sie unter [File System](https://wingo-ui.com/components/file-system) aus und installier sie mit `npx wingo-ui@latest add file-system`.

## Wie verbinde ich einen React File Manager mit meinen Daten?

Übergib alle Ordner und Dateien als ein flaches `items`-Array und schalte jede Aktion ein, indem du ihren Handler übergibst. Jedes Element ist `{ id, kind, name, parentId, size, type, url, modifiedAt, modifiedBy }`, und die Komponente leitet Ordner, Baum und Breadcrumb aus den `parentId`-Verknüpfungen ab. `onUpload` ergänzt den Upload-Button und Drag and Drop, `onMove` das Ziehen auf Ordner und den Dialog zum Verschieben, `onRename`, `onDelete` und `onCreateFolder` den Rest. Lässt du alle weg, ist sie ein reiner Viewer.

Zwei Details sorgen dafür, dass die Fehlerzustände funktionieren. Ein Handler, der ein abgelehntes Promise zurückgibt, hält seinen Dialog oder sein Umbenennen-Feld mit der Fehlermeldung offen. Ein doppelter Name oder eine abgebrochene Verbindung erscheint also genau dort, wo die Person hinschaut. Und den Upload-Fortschritt meldest du selbst über das Prop `uploads`, das das schwebende Upload-Panel füttert.

```tsx
"use client";

import { useState } from "react";
import { FileManager, type FileManagerItem, type FileManagerUpload } from "@/components/ui/file-manager";

async function api<T>(url: string, init?: RequestInit): Promise<T> {
  const res = await fetch(url, { ...init, headers: { "Content-Type": "application/json" } });
  if (!res.ok) {
    const body = await res.json().catch(() => null);
    throw new Error(body?.message ?? `Anfrage fehlgeschlagen (${res.status})`);
  }
  // Umbenennen, Verschieben und Löschen dürfen mit 204 ohne Body antworten
  return (res.status === 204 ? undefined : await res.json()) as T;
}

// xhr, weil fetch kein Event für den Upload-Fortschritt hat
function put(url: string, file: File, type: string, onProgress: (progress: number) => void) {
  return new Promise<void>((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.upload.onprogress = (event) => {
      if (event.lengthComputable) onProgress(event.loaded / event.total);
    };
    xhr.onload = () => (xhr.status >= 200 && xhr.status < 300 ? resolve() : reject(new Error(`Upload fehlgeschlagen (${xhr.status})`)));
    xhr.onerror = () => reject(new Error("Netzwerkfehler"));
    xhr.open("PUT", url);
    // muss dem Content-Type entsprechen, mit dem die URL signiert wurde
    xhr.setRequestHeader("Content-Type", type);
    xhr.send(file);
  });
}

export function ClientDocuments({ clientId, initial }: { clientId: string; initial: FileManagerItem[] }) {
  const [items, setItems] = useState(initial);
  const [uploads, setUploads] = useState<FileManagerUpload[]>([]);
  const base = `/api/clients/${clientId}/files`;

  async function uploadOne(file: File, folderId: string | null) {
    const id = crypto.randomUUID();
    const type = file.type || "application/octet-stream";
    const patch = (next: Partial<FileManagerUpload>) =>
      setUploads((list) => list.map((upload) => (upload.id === id ? { ...upload, ...next } : upload)));
    setUploads((list) => [...list, { id, name: file.name, size: file.size, progress: 0, status: "uploading", folderId }]);
    try {
      const { uploadUrl, fileId } = await api<{ uploadUrl: string; fileId: string }>(`${base}/uploads`, {
        method: "POST",
        body: JSON.stringify({ name: file.name, size: file.size, type, folderId }),
      });
      await put(uploadUrl, file, type, (progress) => patch({ progress }));
      const saved = await api<FileManagerItem>(`${base}/${fileId}/complete`, { method: "POST" });
      setItems((list) => [...list, saved]);
      patch({ progress: 1, status: "done" });
    } catch (error) {
      patch({ status: "error", error: error instanceof Error ? error.message : "Upload fehlgeschlagen" });
    }
  }

  return (
    <FileManager
      items={items}
      uploads={uploads}
      rootLabel="Kundendateien"
      persistKey={`client-files:${clientId}`}
      accept="image/*,.pdf,.docx,.xlsx"
      maxFileSize={50 * 1024 * 1024}
      onUpload={(files, folderId) => Promise.all(files.map((file) => uploadOne(file, folderId)))}
      onCreateFolder={async (name, parentId) => {
        const folder = await api<FileManagerItem>(`${base}/folders`, { method: "POST", body: JSON.stringify({ name, parentId }) });
        setItems((list) => [...list, folder]);
      }}
      onRename={async (item, name) => {
        await api(`${base}/${item.id}`, { method: "PATCH", body: JSON.stringify({ name }) });
        setItems((list) => list.map((i) => (i.id === item.id ? { ...i, name } : i)));
      }}
      onMove={async (ids, parentId) => {
        await api(`${base}/move`, { method: "POST", body: JSON.stringify({ ids, parentId }) });
        setItems((list) => list.map((i) => (ids.includes(i.id) ? { ...i, parentId } : i)));
      }}
      onDelete={async (ids) => {
        await api(base, { method: "DELETE", body: JSON.stringify({ ids }) });
        setItems((list) => list.filter((i) => !ids.includes(i.id)));
      }}
    />
  );
}
```

`accept` und `maxFileSize` lehnen Dateien ab, bevor `onUpload` läuft, und das Upload-Panel listet sie mit der Begründung auf. Dein Server prüft beides trotzdem, denn jeder Client kann den Endpunkt aufrufen. Den Upload-Ablauf selbst (Drag and Drop, Einfügen, Fortschritt, Abbrechen) behandelt unser [Guide zum React File Upload](https://wingo-ui.com/de/blog/react-file-upload) ausführlich, und die eigenständige Dropzone ist die [Komponente File Upload](https://wingo-ui.com/components/file-upload).

## Welchen Backend-Vertrag braucht ein File Manager?

Ein File Manager braucht sieben Endpunkte (Auflisten, neuer Ordner, Umbenennen, Verschieben, Löschen, Hochladen, Herunterladen), die über stabile IDs arbeiten und auf dem Server geprüft werden. Das gilt für jeden React File Manager, den du wählst, ob Open Source oder nicht:

| Aktion | Request | Zugehöriges Prop |
|---|---|---|
| Auflisten | `GET /files` (oder pro Ordner) liefert Zeilen mit `id`, `parentId`, `name`, `kind` | `items` oder `loadChildren` in File System |
| Neuer Ordner | `POST /files/folders { name, parentId }` liefert die Zeile | `onCreateFolder` |
| Umbenennen | `PATCH /files/:id { name }` | `onRename` |
| Verschieben | `POST /files/move { ids, parentId }` | `onMove` |
| Löschen | `DELETE /files { ids }` | `onDelete` |
| Hochladen | `POST /files/uploads` liefert eine Presigned URL; `POST /files/:id/complete` legt die Zeile an | `onUpload` + `uploads` |
| Herunterladen | `GET /files/:id/download` leitet auf eine kurzlebige Storage-URL weiter | `url`, `onDownload` oder `resolveUrl` in File System |

Die Regeln, die das korrekt halten:

1. **IDs statt Pfaden.** Speicher eine stabile id und eine `parentId`. Ist ein Pfad wie `/Contracts/2026/acme.pdf` der Schlüssel, schreibt das Umbenennen eines Ordners jede Zeile darunter neu, und jeder geteilte Link bricht.
2. **Jede ID autorisieren.** Jeder Request prüft, dass jede enthaltene ID zum Mandanten und zum Datensatz aus der URL gehört. Ein Massenlöschen mit einer einzigen fremden ID sollte komplett fehlschlagen.
3. **Namenskonflikte entscheidet der Server.** Zwei Leute können im selben Moment im selben Ordner „Rechnungen“ anlegen. Leg eine Regel fest (mit einer klaren Meldung ablehnen oder „ (2)“ anhängen) und gib den Fehlertext zurück, den der Dialog anzeigt.
4. **Storage-Schlüssel sind keine Dateinamen.** Laut der [AWS-Doku zu Presigned Uploads](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html) (geprüft am 6. November 2026) ersetzt S3 ein bestehendes Objekt, wenn ein Upload denselben Schlüssel nutzt. Nimm die Datei-ID als Schlüssel und halte den Namen in deiner Datenbank. Dieselbe Doku sagt auch: Ist die URL mit einem Content-Type signiert, muss der Upload genau diesen mitschicken. Deshalb signiert und sendet das Beispiel denselben Wert.
5. **Uploads an deinen Functions vorbei.** Vercel Functions nehmen Request-Bodys bis 4,5 MB an und antworten darüber mit 413, laut [Vercels Seite zu den Limits](https://vercel.com/docs/functions/limitations) (Stand 6. November 2026). Presigned URLs schicken die Bytes direkt in den Storage.
6. **Erst Soft Delete.** Markier Zeilen als gelöscht und entferne sie später endgültig. Leute löschen den falschen Ordner, und das Löschen eines Ordners trifft einen ganzen Teilbaum.
7. **Zyklen auf dem Server ablehnen.** Die Oberfläche verhindert schon, dass jemand einen Ordner auf sich selbst oder einen seiner Unterordner zieht, aber der Move-Endpunkt muss das noch einmal prüfen:

```ts
type FolderRow = { id: string; parentId: string | null };

// false, wenn das Ziel einer der verschobenen Ordner ist oder in einem davon liegt
export function canMove(folders: FolderRow[], ids: string[], targetId: string | null) {
  const parentOf = new Map(folders.map((folder) => [folder.id, folder.parentId]));
  const moving = new Set(ids);
  const seen = new Set<string>();
  for (let at: string | null = targetId; at !== null; at = parentOf.get(at) ?? null) {
    if (moving.has(at) || seen.has(at)) return false;
    seen.add(at);
  }
  return true;
}
```

Führ die Prüfung in derselben Transaktion wie das Update aus, nachdem du die Ordnerzeilen des Mandanten gesperrt hast (`SELECT ... FOR UPDATE` in Postgres), oder unter Serializable Isolation. Eine einfache Transaktion auf der Standard-Isolationsstufe lässt zwei gleichzeitige Verschiebungen, A in B und B in A, beide die Prüfung bestehen, und schon entsteht ein Zyklus. Das Set `seen` beendet den Durchlauf außerdem, falls kaputte Daten schon einen Zyklus enthalten.

## Wie funktioniert ein File Manager auf dem Smartphone?

Auf dem Smartphone ersetzt der File Manager Hover, Rechtsklick und Ziehen durch Tippen, langes Drücken und Bottom Sheets. Er startet dort als Liste, mit dem Ordnernamen als großem Titel und einem Zurück-Link zum übergeordneten Ordner statt der vollen Breadcrumb. Ein Tipp öffnet, langes Drücken startet die Auswahl (Checkboxen erscheinen, und eine schwebende Leiste bietet Verschieben, Herunterladen und Löschen an), und jedes Menü, der Dialog zum Verschieben und der Dialog für einen neuen Ordner öffnen sich als Bottom Sheets. Das Layout richtet sich über Container Queries nach der Breite der Komponente selbst. Dieselbe kompakte Liste erscheint also auch in einem schmalen Seitenpanel auf einem großen Bildschirm, und der Ordnerbaum zeigt sich erst, wenn der Manager selbst 768px breit ist.

Zur Barrierefreiheit: Die Dateien sind ein einziger Tab-Stopp mit Pfeiltasten-Navigation darin, Buchstaben springen zu einem Namen, die Leertaste schaltet die Auswahl um, Shift + F10 öffnet das Menü des Elements, und Entf fragt nach, bevor etwas verschwindet. Das Menü, das ein Rechtsklick öffnet, steckt auch hinter einem ⋯-Button pro Element. Der erscheint bei Hover, bei Tastaturfokus und bei Auswahl und bleibt auf Touchscreens sichtbar, also hängt nichts an einer Maus.

## Gibt es einen guten Open Source React File Manager?

Ja, und für viele Projekte ist ein kostenloses Paket die richtige Antwort. Zwei Projekte unter MIT-Lizenz lohnen Stand 6. November 2026 einen Blick (Sterne laut GitHub an diesem Tag):

| Projekt | Lizenz | Datenmodell | Hinweise |
|---|---|---|---|
| [@cubone/react-file-manager](https://github.com/Saifullah-dev/react-file-manager) | MIT | `files`-Array aus `{ name, isDirectory, path }` | Raster und Liste, `fileUploadConfig` sendet an deinen Endpunkt, `permissions`-Flags, ein Beispiel-Backend mit Node und MongoDB; 158 GitHub-Sterne |
| [SVAR React File Manager](https://svar.dev/react/filemanager/) | MIT | `data`-Array mit Pfad-IDs wie `/Music` | Liste, Kacheln und eine geteilte Ansicht, ein Baum und Breadcrumbs, Ordner werden beim Öffnen geladen, helles und dunkles Theme; 87 GitHub-Sterne ([Repo](https://github.com/svar-widgets/react-filemanager)) |
| [Wingo UI File Manager](https://wingo-ui.com/components/file-manager) | Pro, Quellcode wird in dein Repo kopiert | Flache `items` mit `parentId` | Raster und Liste, Baum, Upload-Panel, Massenaktionen, Smartphone-Layout mit Sheets, Defaults über `UIProvider` |

Nimm @cubone oder SVAR, wenn du einen kostenlosen React File Explorer zum direkten Einbauen willst und mit seinem Aussehen und seinen pfadbasierten IDs leben kannst. Nimm eine Komponente als Quellcode, wenn der File Manager zum Rest deines Design Systems passen muss und du damit rechnest, sein Markup zu ändern: Die Datei gehört dir, und `npx wingo-ui@latest update` führt unsere späteren Fixes mit deinen Änderungen zusammen. Wingo UI ist eine kostenpflichtige Bibliothek: Pro kostet $8 im Monat, $80 im Jahr oder einmalig $150, siehe [Preise](https://wingo-ui.com/de/pricing). Die 14-tägige Rückerstattung gilt nur, solange du noch kein Pro-Element heruntergeladen hast.

## Wann reicht ein Tree View?

Ein Tree View reicht, wenn Leute Ordner auswählen oder anordnen und nie mit den Dateien darin arbeiten: ein Einstellungsscreen, der einen Zielordner wählt, eine Seitenleiste mit Projektbereichen oder ein Browser für Codebeispiele. Der [Tree View](https://wingo-ui.com/components/tree-view) ist dieselbe Komponente, die der File Manager für seine Ordner nutzt: lazy children über `loadChildren`, Verschieben per Drag mit `draggable` und `onMove`, Filtern und Ordner-Icons. Unser [Guide zum React Tree View](https://wingo-ui.com/de/blog/react-tree-view) geht ihn Schritt für Schritt durch, und die [Kategorie Komponenten-Guides](https://wingo-ui.com/de/blog/category/components) enthält den Rest dieser Reihe, mit dem [Guide zu React-Formularkomponenten](https://wingo-ui.com/de/blog/react-form-components-guide) als Überblick.

## Nächster Schritt

Öffne die [Doku zum File Manager](https://wingo-ui.com/components/file-manager), ändere im Playground Ansicht, Kachelgröße und Tone und kopier den Usage-Code mit deinen eigenen `items` in eine Seite. Schreib danach die sieben Endpunkte von oben, bevor du irgendetwas stylst, denn genau dort gehen Datei-Features in Produktion kaputt. Beide Datei-Komponenten sind Pro; die Doku, der Playground und der [MCP-Server](https://wingo-ui.com/docs/mcp) funktionieren ohne Account.

## Komponenten in diesem Artikel

- [File manager](https://wingo-ui.com/components/file-manager) (Pro): A React file manager for the documents of a company or a record: folders and files in a grid or a list, a folder tree, uploads and bulk actions. Installation: `npx wingo-ui@latest add file-manager`
- [File System](https://wingo-ui.com/components/file-system) (Pro): A React file browser in the style of Finder: a sidebar, icons, list, columns and gallery views, a preview panel and Quick Look on real documents. Installation: `npx wingo-ui@latest add file-system`
- [Tree View](https://wingo-ui.com/components/tree-view) (Pro): A React tree view for folders, categories or permissions: animated expand, selection, tri-state checkboxes, filter and drag to move. Installation: `npx wingo-ui@latest add tree-view`
- [File Upload](https://wingo-ui.com/components/file-upload) (Pro): A React file upload with drag and drop, paste and camera capture: validation, previews, per-file progress, and list, grid or avatar layouts. Installation: `npx wingo-ui@latest add file-upload`

## Häufige Fragen

### Was ist der Unterschied zwischen einem File Manager und einem File Explorer in React?

Beide Begriffe meinen dasselbe: eine Oberfläche, die Ordner und Dateien auflistet und sie öffnen, verschieben, umbenennen und hochladen lässt. In der Praxis gibt es zwei Formen: einen Dokumentenmanager in einer App-Seite (Raster oder Liste, ein Baum, Massenaktionen) und einen File Browser im Desktop-Stil mit Seitenleiste, mehreren Ansichten und Vorschauen. Entscheide danach, wie Leute die Dateien nutzen, nicht nach dem Namen.

### Gibt es einen kostenlosen Open Source React File Manager?

Ja. Stand 6. November 2026 stehen @cubone/react-file-manager und SVAR React File Manager (@svar-ui/react-filemanager) beide unter MIT-Lizenz auf GitHub. Beide überlassen dir den Storage über Callbacks oder ein Daten-Prop, das Backend schreibst du also trotzdem selbst.

### Wie speichere ich Ordner für einen React File Manager?

Speicher jeden Ordner und jede Datei als Zeile mit einer stabilen id und einer parentId (null im Stammverzeichnis) und den Namen als einfache Spalte. Ein Umbenennen ändert dann eine Zeile, ein Verschieben eine parentId, und Links auf eine Datei überstehen beides.

### Wie lade ich große Dateien aus einem React File Manager hoch?

Hol dir von deiner API eine Presigned URL für den Storage, schick die Datei vom Browser mit XMLHttpRequest direkt dorthin, damit du Fortschritts-Events bekommst, und bestätige den Upload, damit der Server die Datei-Zeile anlegt. So laufen die Bytes nicht durch Serverless Functions, die Vercel auf 4,5 MB pro Request-Body begrenzt.

### Wie verhindere ich, dass ein Ordner in seinen eigenen Unterordner verschoben wird?

Geh vom Zielordner aus die Eltern nach oben durch; triffst du dabei auf einen der Ordner, die verschoben werden, lehnst du ab. Die Oberfläche kann das früh blockieren, aber der Server muss es ebenfalls prüfen, denn jeder Client kann deinen Move-Endpunkt aufrufen.

---

Quelle: https://wingo-ui.com/de/blog/react-file-manager
