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.