Sync
Files or file data that is uploaded synchronously is sent to the server along with other form data when the users presses the form submit button.
Form post
This is the default upload method. When we wrap a <input type="file"/> with the <file-pond> custom element we get the FilePond user experience and files are still uploaded to our server when the form is posted.
Pros:
- Easy to set up
- Perfectly fine for smaller files
- Straightforward UX
Cons:
- No way to gauge upload progress
- Can’t abort upload
- Larger files will make the page seem stuck
- No pause/resume
In short, this is perfectly fine for uploading some small files. But uploading larger files or multiple small files on a slow connection will potentially cause user experience problems.
<form action="/upload" method="POST">
<label for="my-file">Document</label>
<file-pond>
<input id="my-file" type="file" name="files" required />
</file-pond>
<button type="submit">Upload</button>
</form>
<script typ="module">
import { defineFilePond } from 'filepond';
import { locale } from 'filepond/locales/en-gb.js';
defineFilePond({
locale,
});
</script>
Local dataURL
Combine the DataURLStore with the TextInputStore to store a dataURL of the file object in the entry and upload files as Base64 strings.
Same pros and cons as the default form post but with issues caused by the additional CPU and memory load.
Async
Asychronously uploaded files are uploaded when they’re added to FilePond, either automatically or by clicking an “upload file” button. When the parent form is posted only the server id’s of the uploaded files are uploaded with the rest of the form.
Form post
A nice middle ground for when we’re uploading slightly larger files. We can register the FormPostStore extension which adds asynchronous file uploading.
When this store is added FilePond automatically adds an upload button to each entry item. Files are posted to an end point on the server. The FormPostStore page in the docs includes a section on configuring our server.
Pros:
- Upload progress indicator per file
- Supports bigger and more files
- User can abort uploads
Cons:
- Requires some backend work
- On unstable connections huge files might fail to upload
- No pause/resume
In short, this is perfectly fine for uploading relatively small files. Uploading large files or uploading multiple small files on a slow or unstable connection could cause user experience problems in the form of failed uploads. For those situations using chunked uploads is a better solution.
import { defineFilePond } from 'filepond';
import { locale } from 'filepond/locales/en-gb.js';
import { FormPostStore } from 'filepond/extensions/form-post-store.js';
defineFilePond({
locale,
extensions: [
[
FormPostStore,
{
// The URL the store will POST files to
url: '/upload',
// The name of the form field we'll use
name: 'files',
},
],
],
});
Chunked file uploads
To do chunked file uploads we can replace the FormPostStore extension with the ChunkedUploadStore when we need to upload very large files.
Pros:
- Upload progress indicator per file
- Great for all kinds of file sizes
- User can abort uploads
- More stable file uploads
Cons:
- Requires more integration work
import { defineFilePond } from 'filepond';
import { locale } from 'filepond/locales/en-gb.js';
import { ChunkedUploadStore } from 'filepond/extensions/chunked-upload-store.js';
defineFilePond({
locale,
extensions: [
[
ChunkedUploadStore,
{
// The URL the store will send files to
url: '/upload',
},
],
],
});
Restoring uploaded files
The FormPostStore and ChunkedUploadStore will both try to restore an uploaded file if the value property on the file entry state is set.
They’ll optionally fire a HEAD request to ?id=<file-server-id> to get the file information. Then they’ll fire a GET request to the same URL to request the file data.
We can manipulate the request object using the resolveRequest and resolveResponse properties.
import { defineFilePond } from 'filepond';
import { locale } from 'filepond/locales/en-gb.js';
import { FormPostStore } from 'filepond/extensions/form-post-store.js';
const [element] = defineFilePond({
locale,
extensions: [
[
FormPostStore,
{
// set to `false` to skip HEAD request
fetchMetadata: true,
// the URL to post files to
url: '/upload',
},
],
],
});
element.entries = [
{
state: {
// the entry server id, FormPostStore will request file at /upload?id=1234
value: '1234',
},
},
];
Alternatively one can use the URLLoader extension to load files from a given URL.
Instant upload
The FormPostStore and ChunkedUploadStore accept the shouldStore option, this option can be set to a (optionally async) function that returns true if the file should be uploaded immediately.
import { defineFilePond } from 'filepond';
import { locale } from 'filepond/locales/en-gb.js';
import { FormPostStore } from 'filepond/extensions/form-post-store.js';
defineFilePond({
locale,
extensions: [
[
FormPostStore,
{
// The URL the store will POST files to
url: '/upload',
// When a file is added it's instantly uploaded
shouldStore: (entry) => true,
},
],
],
});
Trigger upload
We can trigger file upload programmatically by setting the store property on one or more entries.
<form action="/upload" method="POST">
<label for="my-file">Document</label>
<file-pond>
<input id="my-file" type="file" name="files" required />
</file-pond>
<button type="button" id="myUploadButton">Store files</button>
<button type="submit">Upload</button>
</form>
<script type="module">
import { defineFilePond } from 'filepond';
import { locale } from 'filepond/locales/en-gb.js';
import { FormPostStore } from 'filepond/extensions/form-post-store.js';
const [element] = defineFilePond({
locale,
extensions: [
[
FormPostStore,
{
// The URL the store will POST files to
url: '/upload',
},
],
],
});
// On click for every entry in this element set the `store` state to `true`
myUploadButton.onclick = function () {
element.entries = element.entries.map((entry) => {
entry.state = { ...entry.state, store: true };
return entry;
});
};
</script>
Simulating file uploads
To test upload functionality we can use the SimulatedStore, it’ll behave just like the FormPostStore but files won’t be uploaded.
Creating a custom store
We can use the createStoreExtension function to create custom stores.