The Inspatial Cloud Client SDK provides a powerful file upload system through the uploadFile method, supporting progress tracking, automatic image optimization, and flexible access control.
Basic File Upload
Upload a file with minimal configuration.
Get the file from user input
Obtain a File object from an input element or file picker: const fileInput = document . querySelector < HTMLInputElement >( '#file-input' );
const file = fileInput . files ?.[ 0 ];
if ( ! file ) {
console . error ( 'No file selected' );
return ;
}
Upload the file
Call uploadFile with the file and filename: client . uploadFile ({
fileName: 'document.pdf' ,
file: file ,
completeCallback : ( uploadedFile ) => {
console . log ( 'Upload complete!' );
console . log ( 'File ID:' , uploadedFile . id );
}
});
Upload with Progress Tracking
Monitor upload progress to provide feedback to users.
client . uploadFile ({
fileName: 'large-video.mp4' ,
file: file ,
progressCallback : ( progress ) => {
if ( progress . lengthComputable ) {
const percentComplete = ( progress . loaded / progress . total ) * 100 ;
console . log ( `Upload progress: ${ percentComplete . toFixed ( 2 ) } %` );
// Update progress bar in UI
updateProgressBar ( percentComplete );
}
},
completeCallback : ( uploadedFile ) => {
console . log ( 'Upload finished:' , uploadedFile . id );
showSuccessMessage ( 'File uploaded successfully!' );
}
});
Image Upload with Optimization
Automatically optimize images during upload to reduce file size and dimensions.
Resize to Maximum Width
client . uploadFile ({
fileName: 'photo.jpg' ,
file: imageFile ,
optimize: {
width: 1920 // Max width in pixels
},
completeCallback : ( uploadedFile ) => {
console . log ( 'Optimized image uploaded:' , uploadedFile . id );
}
});
Resize to Maximum Height
client . uploadFile ({
fileName: 'portrait.jpg' ,
file: imageFile ,
optimize: {
height: 1080 // Max height in pixels
}
});
Resize with Both Dimensions
client . uploadFile ({
fileName: 'thumbnail.jpg' ,
file: imageFile ,
optimize: {
width: 300 ,
height: 300 // Maintains aspect ratio within these bounds
},
completeCallback : ( uploadedFile ) => {
console . log ( 'Thumbnail created:' , uploadedFile . id );
}
});
Image optimization maintains aspect ratio. If you specify both width and height, the image will be scaled to fit within those dimensions while preserving its original proportions.
Public vs Private Files
Control file access with public and private settings.
Upload Public File
// Public files are accessible without authentication
client . uploadFile ({
fileName: 'company-logo.png' ,
file: file ,
publicFile: true , // Anyone can access this file
completeCallback : ( uploadedFile ) => {
console . log ( 'Public file URL:' , uploadedFile . url );
// Use this URL directly in <img> tags or share publicly
}
});
Upload Private File
// Private files require authentication to access
client . uploadFile ({
fileName: 'confidential-report.pdf' ,
file: file ,
publicFile: false , // Default: requires authentication
completeCallback : ( uploadedFile ) => {
console . log ( 'Private file uploaded:' , uploadedFile . id );
// File requires user authentication to access
}
});
Global vs User-Scoped Files
Determine file visibility scope across your application.
// User-scoped file (default)
client . uploadFile ({
fileName: 'user-avatar.jpg' ,
file: file ,
global: false , // Only accessible by the uploading user
completeCallback : ( uploadedFile ) => {
console . log ( 'User file uploaded:' , uploadedFile . id );
}
});
// Global file
client . uploadFile ({
fileName: 'shared-resource.pdf' ,
file: file ,
global: true , // Accessible by all authenticated users
completeCallback : ( uploadedFile ) => {
console . log ( 'Global file uploaded:' , uploadedFile . id );
}
});
Be careful when uploading files as global. Ensure the file content is appropriate for all users in your application.
Error Handling
Handle upload errors gracefully.
client . uploadFile ({
fileName: 'document.docx' ,
file: file ,
progressCallback : ( progress ) => {
const percent = ( progress . loaded / progress . total ) * 100 ;
updateProgressBar ( percent );
},
completeCallback : ( uploadedFile ) => {
hideProgressBar ();
showSuccessMessage ( 'Upload successful!' );
console . log ( 'File ID:' , uploadedFile . id );
},
errorCallback : ( error ) => {
hideProgressBar ();
showErrorMessage ( 'Upload failed. Please try again.' );
console . error ( 'Upload error:' , error );
},
abortCallback : () => {
hideProgressBar ();
showInfoMessage ( 'Upload cancelled.' );
console . log ( 'Upload aborted by user' );
}
});
Complete Upload Component Example
Here’s a complete example with progress tracking and optimization:
import { InCloudClient } from '@inspatial/cloud-client' ;
const client = new InCloudClient ( 'https://api.yourapp.com' );
class FileUploader {
private progressBar : HTMLProgressElement ;
private statusText : HTMLSpanElement ;
constructor () {
this . progressBar = document . querySelector ( '#upload-progress' ) ! ;
this . statusText = document . querySelector ( '#upload-status' ) ! ;
}
async uploadImage ( file : File ) : Promise < string > {
return new Promise (( resolve , reject ) => {
// Validate file type
if ( ! file . type . startsWith ( 'image/' )) {
reject ( new Error ( 'Please select an image file' ));
return ;
}
// Validate file size (max 10MB)
const maxSize = 10 * 1024 * 1024 ;
if ( file . size > maxSize ) {
reject ( new Error ( 'File size must be less than 10MB' ));
return ;
}
this . statusText . textContent = 'Uploading...' ;
this . progressBar . style . display = 'block' ;
client . uploadFile ({
fileName: file . name ,
file: file ,
publicFile: true ,
optimize: {
width: 1920 ,
height: 1080
},
progressCallback : ( progress ) => {
if ( progress . lengthComputable ) {
const percent = ( progress . loaded / progress . total ) * 100 ;
this . progressBar . value = percent ;
this . statusText . textContent = `Uploading... ${ percent . toFixed ( 0 ) } %` ;
}
},
completeCallback : ( uploadedFile ) => {
this . progressBar . style . display = 'none' ;
this . statusText . textContent = 'Upload complete!' ;
console . log ( 'File uploaded successfully:' , uploadedFile );
resolve ( uploadedFile . id );
},
errorCallback : ( error ) => {
this . progressBar . style . display = 'none' ;
this . statusText . textContent = 'Upload failed' ;
console . error ( 'Upload error:' , error );
reject ( new Error ( 'Upload failed' ));
},
abortCallback : () => {
this . progressBar . style . display = 'none' ;
this . statusText . textContent = 'Upload cancelled' ;
reject ( new Error ( 'Upload cancelled' ));
}
});
});
}
async uploadDocument ( file : File , isPublic : boolean = false ) : Promise < string > {
return new Promise (( resolve , reject ) => {
this . statusText . textContent = 'Uploading document...' ;
client . uploadFile ({
fileName: file . name ,
file: file ,
publicFile: isPublic ,
global: false ,
progressCallback : ( progress ) => {
if ( progress . lengthComputable ) {
const percent = ( progress . loaded / progress . total ) * 100 ;
this . statusText . textContent =
`Uploading... ${ this . formatBytes ( progress . loaded ) } / ${ this . formatBytes ( progress . total ) } ` ;
}
},
completeCallback : ( uploadedFile ) => {
this . statusText . textContent = 'Document uploaded!' ;
resolve ( uploadedFile . id );
},
errorCallback : ( error ) => {
this . statusText . textContent = 'Upload failed' ;
reject ( error );
}
});
});
}
private formatBytes ( bytes : number ) : string {
if ( bytes === 0 ) return '0 Bytes' ;
const k = 1024 ;
const sizes = [ 'Bytes' , 'KB' , 'MB' , 'GB' ];
const i = Math . floor ( Math . log ( bytes ) / Math . log ( k ));
return Math . round ( bytes / Math . pow ( k , i ) * 100 ) / 100 + ' ' + sizes [ i ];
}
}
// Usage
const uploader = new FileUploader ();
// Handle file input
const fileInput = document . querySelector < HTMLInputElement >( '#file-input' ) ! ;
fileInput . addEventListener ( 'change' , async ( e ) => {
const file = ( e . target as HTMLInputElement ). files ?.[ 0 ];
if ( file ) {
try {
if ( file . type . startsWith ( 'image/' )) {
const fileId = await uploader . uploadImage ( file );
console . log ( 'Image uploaded with ID:' , fileId );
} else {
const fileId = await uploader . uploadDocument ( file , false );
console . log ( 'Document uploaded with ID:' , fileId );
}
} catch ( error ) {
console . error ( 'Upload failed:' , error );
}
}
});
Method Signature
uploadFile ( options : {
fileName: string ;
file : File ;
global ?: boolean ;
publicFile ?: boolean ;
optimize ?: {
width? : number ;
height ?: number ;
};
progressCallback ?: ( progress : ProgressEvent , uid ?: string ) => void ;
completeCallback ?: ( file : Entry ) => void ;
errorCallback ?: ( response : unknown , uid ?: string ) => void ;
abortCallback ?: ( response : unknown , uid ?: string ) => void ;
}): void
Upload Options Reference
Option Type Description Default fileNamestringName to save the file as Required fileFileThe file object to upload Required globalbooleanMake file accessible to all authenticated users falsepublicFilebooleanMake file publicly accessible without authentication falseoptimize.widthnumberMaximum width for image optimization (pixels) - optimize.heightnumberMaximum height for image optimization (pixels) - progressCallbackfunctionCalled with progress updates during upload - completeCallbackfunctionCalled when upload completes successfully - errorCallbackfunctionCalled if upload fails - abortCallbackfunctionCalled if upload is aborted -
Accessing Uploaded Files
After uploading, you can access file URLs through the client.
const fileUrl = ` ${ client . filesEndpoint }${ uploadedFile . id } ` ;
// Use in an image tag
const img = document . createElement ( 'img' );
img . src = fileUrl ;
// Or download link
const link = document . createElement ( 'a' );
link . href = fileUrl ;
link . download = uploadedFile . fileName ;
Best Practices
Validate Before Upload Always validate file type and size on the client side before uploading to save bandwidth and improve UX.
Show Progress Use progress callbacks to keep users informed during long uploads.
Optimize Images Use image optimization to reduce file sizes and improve load times across your application.
Handle Errors Always implement error and abort callbacks to handle network issues gracefully.
Troubleshooting
Progress callback not firing
The progress callback requires that the server sends appropriate headers. If progress isn’t updating:
Verify your server supports progress events
Check that Content-Length header is being sent
Ensure the upload is large enough to generate progress events
Image optimization not working
Verify the file is actually an image (JPEG, PNG, GIF, WebP)
Check server logs for image processing errors
Ensure image optimization is enabled on your server
Try with a smaller image first to isolate the issue