Introduction
File uploads are a common requirement in Salesforce applications. With Lightning Web Components (LWC), you can easily implement file upload functionality that stores files as Salesforce Files (ContentVersion) or as attachments.
This guide will walk you through the implementation steps.
Method 1: Using lightning-file-upload Component (Recommended)
The easiest way to implement file uploads is using the built-in lightning-file-upload
 component.
Implementation Steps
// fileUpload.js
import { LightningElement, api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
export default class FileUpload extends LightningElement {
@api recordId; // The record ID the files should be attached to
acceptedFormats = ['.pdf', '.png', '.jpg', '.jpeg', '.doc', '.docx'];
handleUploadFinished(event) {
// Get the list of uploaded files
const uploadedFiles = event.detail.files;
// Show success message
this.dispatchEvent(
new ShowToastEvent({
title: 'Success',
message: `${uploadedFiles.length} file(s) uploaded successfully`,
variant: 'success'
})
);
// You might want to refresh related list views here
}
}
Key Attributes:
record-id
: The record to attach files toaccept
: Specifies allowed file typesmultiple
: Allows multiple file selectiononuploadfinished
: Event handler when upload completes
Method 2: Custom File Upload with Apex
For more control over the upload process, you can implement a custom solution:
// fileUploadController.cls (Apex)
public with sharing class FileUploadController {
@AuraEnabled
public static Id saveFile(Id parentId, String fileName, String base64Data) {
ContentVersion cv = new ContentVersion();
cv.VersionData = EncodingUtil.base64Decode(base64Data);
cv.Title = fileName;
cv.PathOnClient = fileName;
cv.FirstPublishLocationId = parentId;
insert cv;
return cv.Id;
}
}
// customFileUpload.js
import { LightningElement, api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import saveFile from '@salesforce/apex/FileUploadController.saveFile';
export default class CustomFileUpload extends LightningElement {
@api recordId;
fileData;
isLoading = false;
handleFileChange(event) {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = () => {
const base64 = reader.result.split(',')[1];
this.fileData = {
'fileName': file.name,
'base64Data': base64
};
};
reader.readAsDataURL(file);
}
handleUpload() {
this.isLoading = true;
saveFile({
parentId: this.recordId,
fileName: this.fileData.fileName,
base64Data: this.fileData.base64Data
})
.then(result => {
this.dispatchEvent(
new ShowToastEvent({
title: 'Success',
message: 'File uploaded successfully',
variant: 'success'
})
);
// Clear the file input
this.template.querySelector('input[type="file"]').value = '';
this.fileData = undefined;
})
.catch(error => {
this.dispatchEvent(
new ShowToastEvent({
title: 'Error uploading file',
message: error.body.message,
variant: 'error'
})
);
})
.finally(() => {
this.isLoading = false;
});
}
}
Best Practices
File Size Limits: Remember Salesforce has file size limits (typically 50MB)
Security: Validate file types on both client and server side
User Feedback: Always provide visual feedback during upload
Error Handling: Handle network issues and server errors gracefully
Mobile Support: Test your upload component on mobile devices
Conclusion
Implementing file uploads in LWC can be as simple as using the standard lightning-file-upload
 component or as customized as building your own solution with Apex. Choose the approach that best fits your requirements, keeping in mind user experience and platform limitations.
For production implementations, consider adding:
Progress indicators for large files
File preview capabilities
Virus scanning integration
Additional metadata capture with files