Default 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">
    <file-pond>
        <label for="my-file">Drop files here, or <u>browse</u></label>
        <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>

Async 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 some small files. But uploading larger files or multiple small files on a slow connection will potentially cause user experience problems.

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',
            },
        ],
    ],
});

Instant upload

The FormPostStore accepts 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, just store it immediately
                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">
    <file-pond>
        <label for="my-file">Drop files here, or <u>browse</u></label>
        <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>

Chunked uploads

We can use the ChunkedUploadStore when we need to upload very large files.

Pros:

  • Upload progress indicator per file
  • Great for all kinds of files
  • User can abort uploads
  • More stable file uploads

Cons:

  • Requires more backend 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',
            },
        ],
    ],
});

Simulated uploads

To test upload functionality we can use the SimulatedStore, it’ll behave just like the FormPostStore but files won’t be uploaded.

Custom stores

We can use the createStoreExtension function to create custom stores.