Back to DocumentationFile Management
File Management System

File Management & Storage

Complete guide to file upload, storage with Vercel Blob, image processing, and file management in NextReady.

Drag & drop uploads
Global CDN storage
Image optimization

File System Features

Vercel Blob Storage
Secure, scalable file storage with global CDN
  • Global edge storage network
  • Automatic HTTPS and compression
  • Built-in CDN acceleration
  • Pay-per-use pricing model
File Upload System
Drag-and-drop uploads with progress tracking
  • Multiple file selection
  • Real-time upload progress
  • File type validation
  • Size limit enforcement
Image Processing
Automatic image optimization and resizing
  • WebP conversion
  • Responsive image variants
  • Thumbnail generation
  • EXIF data handling
Security & Validation
Comprehensive file validation and security
  • File type whitelisting
  • Malware scanning integration
  • User ownership validation
  • Access control permissions

Implementation Guide

File Upload Component
Drag-and-drop file upload with progress tracking and validation
// components/file/FileUpload.tsx
'use client';

import { useState, useCallback } from 'react';
import { useDropzone } from 'react-dropzone';
import { Progress } from '@/components/ui/progress';
import { Button } from '@/components/ui/button';
import { Upload, X } from 'lucide-react';

interface FileUploadProps {
  onUploadComplete?: (files: UploadedFile[]) => void;
  maxFiles?: number;
  maxSize?: number;
  acceptedTypes?: string[];
}

export function FileUpload({
  onUploadComplete,
  maxFiles = 10,
  maxSize = 10 * 1024 * 1024, // 10MB
  acceptedTypes = ['image/*', '.pdf', '.doc', '.docx']
}: FileUploadProps) {
  const [uploadProgress, setUploadProgress] = useState<Record<string, number>>({});
  const [uploadedFiles, setUploadedFiles] = useState<UploadedFile[]>([]);

  const onDrop = useCallback(async (acceptedFiles: File[]) => {
    for (const file of acceptedFiles) {
      await uploadFile(file);
    }
  }, []);

  const uploadFile = async (file: File) => {
    const formData = new FormData();
    formData.append('file', file);

    try {
      const response = await fetch('/api/files/upload', {
        method: 'POST',
        body: formData,
      });

      if (!response.ok) throw new Error('Upload failed');

      const result = await response.json();
      setUploadedFiles(prev => [...prev, result.file]);
      onUploadComplete?.([result.file]);
    } catch (error) {
      console.error('Upload error:', error);
    }
  };

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    maxFiles,
    maxSize,
    accept: acceptedTypes.reduce((acc, type) => {
      acc[type] = [];
      return acc;
    }, {} as Record<string, string[]>),
  });

  return (
    <div className="space-y-4">
      <div
        {...getRootProps()}
        className={`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${
          isDragActive ? 'border-brand-primary bg-brand-primary/5' : 'border-gray-300'
        }`}
      >
        <input {...getInputProps()} />
        <Upload className="mx-auto h-12 w-12 text-gray-400 mb-4" />
        {isDragActive ? (
          <p className="text-brand-primary">Drop files here...</p>
        ) : (
          <div>
            <p className="text-gray-600">Drag files here or click to browse</p>
            <p className="text-sm text-gray-400 mt-2">
              Max {maxFiles} files, up to {Math.round(maxSize / 1024 / 1024)}MB each
            </p>
          </div>
        )}
      </div>

      {uploadedFiles.length > 0 && (
        <div className="space-y-2">
          <h4 className="font-medium">Uploaded Files</h4>
          {uploadedFiles.map((file) => (
            <div key={file.id} className="flex items-center justify-between p-2 border rounded">
              <span className="text-sm">{file.name}</span>
              <span className="text-xs text-gray-500">{formatFileSize(file.size)}</span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

Configuration & Setup

Environment Variables
Required environment variables for file storage
BLOB_READ_WRITE_TOKENRequired

Vercel Blob storage token for read/write operations

vercel_blob_rw_AbCdEfGhIjKlMnOpQrStUvWxYz
Vercel Blob Setup
Steps to configure Vercel Blob storage for your project
1

Enable Vercel Blob

Go to your Vercel dashboard and enable Blob storage for your project

2

Get Access Token

Generate a read-write token from the Blob storage settings

3

Configure Environment

Add BLOB_READ_WRITE_TOKEN to your environment variables

4

Test Upload

Use the file upload components to test your configuration

Security & Best Practices

Common Use Cases

Profile Pictures
User avatar uploads with automatic resizing
  • Square crop and resize to 200x200
  • WebP conversion for optimization
  • Old avatar cleanup on update
Document Storage
Business document management system
  • PDF, DOC, DOCX support
  • Version control and history
  • Access control and sharing

📁 File System Ready!

Your file management system is configured and ready to handle uploads, storage, and processing.