Files are the data type that most often generates costs and risks (privacy, caching, and performance). Treat it as a domain: clear permissions and pipelines.
Objective
- Reliable uploads with limits.
- Controlled access (public vs private) aligned with policies/roles.
- Predictable consumption in the UI (stable URLs, cache, fallback).
Permissions and privacy
Golden rule:
- If the file is private, do not deliver an "open" URL without control.
Checklist:
- Check read permissions for
directus_files(or files collection) and for your project's paths/asset delivery. - If the app requires per-user protection: use mechanisms compatible with tokens/sessions (your deployment's standard).
Uploads
- Set size/type limits in Directus and handle errors in the app.
- Do uploads in clear flows:
- pre-validation (size, mime, extension) on the client
- upload
- confirmation of the item (create/update of the item that references the file)
- For consistency: if writing the item fails after upload, define cleanup or a retention policy.
Asset serving and caching
- Prefer URLs/paths that support CDN caching.
- Configure headers according to type (long cache for static images; short cache for dynamic assets).
- In the UI, use lazy loading when it makes sense, but ensure that above-the-fold content (LCP) does not end up "without media".
Transformations and variants
If the project uses transform/derivations:
- Standardize sizes and formats (e.g., WebP/AVIF for images).
- Ensure the app consumes the correct variant per context (list vs hero).
Integration with the app
- In the app: handle states
uploading,failed,retry. - Expose to the UI only:
id/reference of the file- final URL (or URL builder) ready for consumption
- minimal metadata (name, size, mime) if needed
Anti-patterns
- Asset URLs exposed for private files
- Upload without handling size and mime (can become an attack vector)
- Loading media without considering LCP/CLS
- Referencing files without confirming persistence/association with the item
Completion criteria
- Upload and association with the item are consistent
- Private permissions work (unauthorized users cannot access)
- UI consumes assets with cache and fallback