You'll need to implement workarounds as of now if you need custom functionality w.r.t uploading files.
The max content limit for AuraEnabled methods as mentioned by Pranay Jaiswal is 4MB, which is also reduced when it is encoded into base64 and gives you a final size limit around 1.5 -2 MB that you'll be able to upload.
One of the workarounds would involve implement using Chatter Rest API and it will support file sizes upto 2GB as mentioned by Bryan Anderson.
Here's what I got for this question, I recently had one such requirement which needed upto 30MB of files to be uploaded using input(type=file). Using AuraEnabled was out of question and I didn't really have time to implement a solution using Chatter Rest API. So, I implemented this:
The solution involves using The AJAX toolkit & a Visualforce Page which helped me overcome the API enabled Session issue withing lightning context.
The html file:
<template>
<div class="slds-hide">
<iframe src="/apex/uploadHelper"></iframe>
</div>
<lightning-input type="file" label="Attachment" onchange={handleFilesChange}>
</lightning-input>
<button onclick={fireToVF}> fire</button>
</template>
The JS controller:
import { LightningElement } from 'lwc';
export default class ApiConnector extends LightningElement {
recordid = '<parent record id>';
connectedCallback(){
window.addEventListener('message', (message)=>{
console.log(message.data);
});
}
toBase64 = file => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
let result = reader.result;
let base64 = 'base64,';
let content = result.indexOf(base64) + base64.length;
let fileContents = result.substring(content);
resolve(fileContents);
}
reader.onerror = error => reject(error);
});
async handleFilesChange(event){
if (event.target.files.length > 0) {
this.file = {
parentRec : this.recordid,
fileName : event.target.files[0].name,
fileContent : await this.toBase64(event.target.files[0])
}
}
}
fireToVF(){
this.fireToComponent(this.file);
}
fireToComponent(message){
this.template.querySelector('iframe').contentWindow.postMessage(message, '*');
}
}
The Visualforce Page within iframe:
<apex:page showHeader="false" sidebar="false" applyBodyTag="false" standardStylesheets="false" >
<script type="text/javascript">__sfdcSessionId = '{!$Api.Session_Id}';</script>
<script src="../../soap/ajax/30.0/connection.js" type="text/javascript"></script>
<script>
function uploadContentVersion(recordId ,filename, filecontent) {
var contentVersion = new sforce.SObject('ContentVersion');
contentVersion.Title = filename;
contentVersion.PathOnClient = '/' + filename;
contentVersion.FirstPublishLocationId = recordId;
contentVersion.VersionData = filecontent;
var results = sforce.connection.create([contentVersion]);
for (var i = 0; i < results.length; i++) {
if (results[i].getBoolean("success")) {
alert('New ContentVersion record created:' + results[i].id);
}
else {
alert('Failed:' + results[i]);
}
}
}
window.addEventListener('message', (message)=>{
console.log(message.data);
var file = message.data;
uploadContentVersion(file.parentRec, file.fileName , file.fileContent);
});
window.parent.postMessage('loaded', "*")
</script>
<body></body>
</apex:page>
Note that this is just an example and may not practice the security requirements required for PostMessage API(checks for Origin and Source).
Since the AJAX toolkit uses SOAP API internally, it has a max limit of 50MB, which due to Base64 Encoding will be reduced from 30-35MB depending on the content in the document.
I had also tried getting the API enabled sessionId from Visualforce page and hitting the Rest api directly from LWC, but the POST fetch request returned 302 and redirected the browser to make a GET request, I'm curious if SF allows POST method over Rest API from LWC/Lightning Context.