When I try to upload a file using Aws-s3-multipart, nothing happens— no upload progress bar, error message, or activity on my aws s3 account. I've installed through the CDN package and included my javascript code through a script tag. Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>VideoUpload</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
</head>
<body>
<%= yield %>
<script src="https://unpkg.com/[email protected]/dist/polyfill.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/tus.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/v0.27.5/dist/uppy.min.js"></script>
<link href="https://transloadit.edgly.net/releases/uppy/v0.27.5/dist/uppy.min.css" rel="stylesheet" />
</body>
<script>
function fileUpload(fileInput) {
fileInput.style.display = 'none'; // uppy will add its own file input
const imagePreview = document.querySelector(".upload-preview");
var uppy = window.Uppy.Core({
id: fileInput.id,
})
.use(window.Uppy.FileInput, {
target: fileInput.parentNode,
})
.use(window.Uppy.Informer, {
target: fileInput.parentNode,
})
.use(window.Uppy.ProgressBar, {
target: imagePreview.parentNode,
});
uppy.use(window.Uppy.AwsS3Multipart, {
serverUrl: '',
});
uppy.on('upload-success', function (file, data, uploadURL) {
console.log("SUCCESS");
// show image preview
imagePreview.src = URL.createObjectURL(file.data)
// construct uploaded file data in the format that Shrine expects
var uploadedFileData = JSON.stringify({
id: uploadURL.match(/\/cache\/([^\?]+)/)[1], // extract key without prefix
storage: 'cache',
metadata: {
size: file.size,
filename: file.name,
mime_type: file.type,
}
});
// set hidden field value to the uploaded file data so that it's submitted with the form as the attachment
var hiddenInput = fileInput.parentNode.querySelector('.upload-hidden')
hiddenInput.value = uploadedFileData;
})
return uppy;
}
document.querySelectorAll("#file-input").forEach( fileInput => {
fileUpload(fileInput)
});
//Move the submit button to the end of the form
const submitButton = document.getElementById('submit');
const uploadForm = document.querySelector('.upload-form');
uploadForm.append(submitButton);
</script>
</html>
The S3 Multipart plugin requires a running Companion server, or custom overrides for the createMultipartUpload, listParts, prepareUploadPart, abortMultipartUpload and completeMultipartUpload options.
uppy.use(window.Uppy.AwsS3Multipart, {
serverUrl: '',
});
If you're using Companion, is that URL correct? You can check the Network tab in the console while uploading, there should be successful requests. If they're failing, please share why!
I'm not using Companion, but rather I mount a Shrine server that points to my S3 endpoint. I followed this tutorial: https://github.com/janko-m/uppy-s3_multipart.
I also don't see any activity on the Network tab when I upload.
@samdealy As of Uppy 0.27 queued files will not automatically start uploading by default, you need to set autoProceed: true.
var uppy = Uppy.Core({
id: fileInput.id,
autoProceed: true,
})
// ...
I haven't yet updated the Shrine examples for Uppy 0.27, but I will do it probably today.
@janko-m I added autoProceed, and still it doesn't upload (no activity on the network tab).
@samdealy Do you see any JavaScript errors in the console? It seems that serverUrl cannot be an empty string after all, I don't remember how it worked at the time I was writing the docs or if I even tried it. Anyway, this example works for me:
<!DOCTYPE html>
<html>
<head>
<title>Uppy AWS S3 Multipart example</title>
<script src="https://transloadit.edgly.net/releases/uppy/v0.27.5/dist/uppy.min.js"></script>
<link href="https://transloadit.edgly.net/releases/uppy/v0.27.5/dist/uppy.min.css" rel="stylesheet" />
</head>
<body>
<div id="upload"></div>
<script>
Uppy.Core({
autoProceed: true,
})
.use(Uppy.FileInput, {
target: '#upload',
})
.use(Uppy.AwsS3Multipart, {
serverUrl: 'https://server.uppy.io/',
})
</script>
</body>
So try setting serverUrl to your app's URL (http://localhost:3000/ for a local Rails app). Alternatively, window.location.origin should give you the current scheme + host, though I'm not sure exactly how widely supported is window.location.origin.
@janko-m I tried setting the serverURL to "http://localhost:3000/", and it didn't work. I then tried using the window.location.origin scheme, and still no network request is made.
@samdealy Can you create a minimal self-contained HTML page that reproduces the issue? The one you posted is in ERB and calls Rails methods, also it has no #file-input field, so it isn't self-contained. When you run the last example I posted, do the requests get made? If so, can you modify that example so that it reproduces your issue?
I'm pretty sure that you somehow just didn't activate Uppy properly, maybe due to some JavaScript error or CSS selector typo.
Thanks for jumping in, @janko-m! I should try Shrine someday, since I don't have a clue how it works :sweat_smile:
One thing that may also help debugging is specifying debug: true:
Uppy.Core({
id: fileInput.id,
autoProceed: true,
debug: true
})
Uppy would then log information to the console about plugins being installed and uploads starting, progressing, and completing. There should be a line like "upload starting" after you've added files.
@janko-m would it make sense if Uppy had a Shrine integration test? We're occasionally seeing users in our issue tracker, so maybe if we can verify things keep working, and have this working integration to point at, that would save every some time. Not exactly sure yet what that would embody and I don't want to derail this discussion, so created https://github.com/transloadit/uppy/issues/1105 for further brainstorming :)
@goto-bus-stop After setting debug to true, this logs to the console:

@janko-m Given the logging output above, it appears that Uppy successfully attaches itself to the html file-input. Do you agree? If not, I will modify the html so that you can replicate it.
@samdealy Yes, it appears the DOM nodes are correctly found, and file is selected. But we would still need it to be replicated in a self-contained example (hopefully it shouldn't be difficult to do). Because, if the file is successfully added, and autoProceed: true is set, then it's hard to tell why the file doesn't proceed to be uploaded. Note that this doesn't appear to be related to the uppy-s3_multipart gem, because Uppy should send some HTTP requests regardless of whether the target endpoints are implemented or not.
I should try Shrine someday, since I don't have a clue how it works 😅
@goto-bus-stop Shrine is in charge of attaching the uploaded files to database records, saving information like location, storage, and some metadata (filesize, filename, MIME type, dimensions etc.) into a database column. This information can afterwards be used to generate URLs to uploaded files, download them, stream them through the app, re-upload them and so on. You can also process derivatives, such as image thumbnails or video screenshots.
But it's a Ruby library, so unless you're developing a Ruby application you won't have use of it 😉
@janko-m Here's my first shot at creating a self-replicated example. Let me know if this doesn't work for you.
<!DOCTYPE html>
<html>
<head>
<title>VideoUpload</title>
</head>
<body>
<table id="TICKER" width="100%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td id="tickerleft"><a href="index.html">←BACK TO TV</a></td>
<td id="tickercenter" class="green redshad"> 8 BALL TV</td>
<td id="tickerright" class="green">
<p id="dater">GET DATE</p>
</td>
</tr>
</tbody>
</table>
<table id="HEAD" width="100%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td id="headleft"><img src="http://8balltv.club/css/8ball.png" /></td>
<td id="headcenter" class="white">Submission Form</td>
<td id="headright"><img src="http://8balltv.club/css/remote.png" width="119" height="99" alt="" /></td>
</tr>
</tbody>
</table>
<div id="DROP"> <input id="file-input" type="file" name="video[file]"></div>
<div id="INPUTS">
<form class="upload-form" action="/video" method="post">
<table id="forma" width="800" border="0" cellspacing="0" cellpadding="10px">
<tbody>
<tr>
<td class="left"> <label for="title" class="label">Title</label> </td>
<td class="right"><input id="title" type="text" name="video[title]" value=""></td>
</tr>
<tr>
<td class="left"><label for="genre" class="label">Genre</label></td>
<td class="right"><input id="genre" type="text" name="video[genre]" value=""></td>
</tr>
<tr>
<td class="left"><label for="uploader_name" class="label optional">Uploader Name</label></td>
<td class="right"><input id="uploader_name" type="text" name="video[uploader_name]" value=""></td>
</tr>
<tr>
<td class="left"><label for="email" class="label">Email</label></td>
<td class="right"><input id="email" type="text" name="video[uploader_email]" value=""></td>
</tr>
<tr>
<td class="left"><label for="end-airing-date" class="label optional">Last Airing Date</label></td>
<td class="right"><input id="end-airing-date" type="date" name="video[end_airing_date]" value=""></td>
</tr>
<tr>
<td class="left">
<section class="series-container"><label for="series" class="label">Part of a series?</label></section>
</td>
<td class="right"><input id="series" type="checkbox" name="video[series]" value=""></td>
</tr>
<tr>
<td class="left"><label for="crew" class="label optional">Crew Info</label></td>
<td class="right">
<textarea id="crew" name="video[crew]"></textarea>
</td>
</tr>
<td class="left"><label for="additional_info" class="label optional ">Additional Info</label></td>
<td class="right">
<textarea id="additional_info" name="video[additional_info]"> </textarea>
</td>
</tr>
</tbody>
</table>
<input type="hidden" name="video[clip]" value="" class="upload-hidden">
</form>
<img class="upload-preview">
</div>
<input id="submit" type="submit" name="" value="Submit">
<script src="https://unpkg.com/[email protected]/dist/polyfill.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/tus.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/v0.27.5/dist/uppy.min.js"></script>
<link href="https://transloadit.edgly.net/releases/uppy/v0.27.5/dist/uppy.min.css" rel="stylesheet" />
</body>
<script>
function fileUpload(fileInput) {
fileInput.style.display = 'none'; // uppy will add its own file input
const imagePreview = document.querySelector(".upload-preview");
var uppy = window.Uppy.Core({
id: fileInput.id,
autoproceed: true,
debug: true
})
.use(window.Uppy.FileInput, {
target: fileInput.parentNode,
})
.use(window.Uppy.Informer, {
target: fileInput.parentNode,
})
.use(window.Uppy.ProgressBar, {
target: imagePreview.parentNode,
});
uppy.use(window.Uppy.AwsS3Multipart, {
serverUrl: 'http://localhost:3000',
});
uppy.on('upload-success', function (file, data, uploadURL) {
imagePreview.src = URL.createObjectURL(file.data)
var uploadedFileData = JSON.stringify({
id: uploadURL.match(/\/cache\/([^\?]+)/)[1],
storage: 'cache',
metadata: {
size: file.size,
filename: file.name,
mime_type: file.type,
}
});
var hiddenInput = fileInput.parentNode.querySelector('.upload-hidden')
hiddenInput.value = uploadedFileData;
})
return uppy;
}
document.querySelectorAll("#file-input").forEach( fileInput => {
fileUpload(fileInput)
});
const submitButton = document.getElementById('submit');
const uploadForm = document.querySelector('.upload-form');
uploadForm.append(submitButton);
</script>
</html>
@samdealy The autoproceed option needs to be in camel case – autoProceed.
@janko-m Thank you, it works.
@samdealy Great 😃
@goto-bus-stop @arturi This issue can be closed.