Plugin structure & registration

Plugin structure

A plugin is an object with a stable id and a setup function:

1import type { UploaderPlugin } from '@uploadcare/file-uploader';
2
3export const myPlugin: UploaderPlugin = {
4 id: 'my-plugin',
5 setup({ pluginApi, uploaderApi }) {
6 // register everything here
7 },
8};

Treat id as the plugin’s identity within a single uploader context. It must be unique for that context.

The setup function receives a single object with the following properties:

PropertyTypeDescription
pluginApiPluginApiPlugin-specific API for registration, config, activity state, and file updates
uploaderApiUploaderPublicApiThe uploader’s public runtime API for actions such as adding files or opening activities

setup can be synchronous or async. It can also return a disposer function that runs when the plugin is unregistered.

Registering plugins

Pass plugins to the <uc-config> element via its plugins property:

1<uc-config id="cfg" ctx-name="my-uploader" pubkey="YOUR_PUBLIC_KEY"></uc-config>
2<uc-file-uploader-regular ctx-name="my-uploader"></uc-file-uploader-regular>
3
4<script type="module">
5 import { myPlugin } from './my-plugin.js';
6
7 const cfg = document.querySelector('#cfg');
8 cfg.plugins = [myPlugin];
9</script>

Or in a framework (React example):

1import { FileUploaderRegular } from '@uploadcare/react-uploader';
2import { myPlugin } from './my-plugin';
3
4export function Uploader() {
5 return <FileUploaderRegular pubkey="YOUR_PUBLIC_KEY" plugins={[myPlugin]} />;
6}

The uploader’s built-in plugins (camera, image editor, external sources, and others) are managed separately and merged in automatically based on your config, so setting plugins only affects your custom plugins.

Plugins are initialized in array order. Replacing cfg.plugins causes the uploader to resync the list: removed plugins are disposed, new plugins are set up, and duplicates by id are skipped.

To add or remove a plugin at runtime, assign a new array to plugins. Mutating the existing array in place — for example with push() or splice() — is not supported and produces non-deterministic results: the mutation may occasionally be picked up due to a timing race with async lazy-plugin loading, but this is not guaranteed and will silently break under different conditions. Always replace the array:

1cfg.plugins = [...cfg.plugins, newPlugin];

Cleanup and disposal

If setup returns a disposer function, it runs when the plugin is removed from the plugins array or when the uploader is destroyed.

1const myPlugin: UploaderPlugin = {
2 id: 'my-plugin',
3 setup({ pluginApi }) {
4 const interval = setInterval(poll, 5000);
5
6 return () => {
7 clearInterval(interval);
8 };
9 },
10};

Subscriptions created with pluginApi.config.subscribe and pluginApi.activity.subscribeToParams inside setup are cleaned up automatically when the plugin is unregistered. If you create subscriptions inside an activity’s render function, unsubscribe them in the cleanup function returned from render so they do not outlive that activity mount.