Skip to main content

React

React components for the Uppy UI plugins and a useUppyState hook.

Install

npm install @uppy/react
note

You also need to install the UI plugin you want to use. For instance, @uppy/dashboard.

Use

@uppy/react exposes component wrappers for Dashboard, DragDrop, and all other UI elements. The components can be used with either React or API-compatible alternatives such as Preact.

caution

If you find yourself writing many instances of useState and useEffect to achieve something with Uppy in React, you are most likely breaking React best practices. Consider reading “You Might Not Need an Effect” and looking at our examples below.

Components

The following components are exported from @uppy/react:

Examples

Example: basic component

Here we have a basic component which ties Uppy’s state to the component. This means you can render multiple instances. But be aware that as your component unmounts, for instance because the user navigates to a different page, Uppy’s state will be lost and uploads will stop.

note

If you render multiple instances of Uppy, make sure to give each instance a unique id.

import React, { useEffect, useState } from 'react';
import Uppy from '@uppy/core';
import Webcam from '@uppy/webcam';
import { Dashboard } from '@uppy/react';

import '@uppy/core/dist/style.min.css';
import '@uppy/dashboard/dist/style.min.css';
import '@uppy/webcam/dist/style.min.css';

function Component() {
// IMPORTANT: passing an initializer function to prevent Uppy from being reinstantiated on every render.
const [uppy] = useState(() => new Uppy().use(Webcam));

return <Dashboard uppy={uppy} plugins={['Webcam']} />;
}

Example: keep Uppy state and uploads while navigating between pages

When you want Uppy’s state to persist and keep uploads running between pages, you can lift the state up.

import React, { useState, useEffect } from 'react';
import Uppy from '@uppy/core';
import { Dashboard } from '@uppy/react';

function Page1() {
// ...
}

function Page2({ uppy }) {
return (
<>
<p>{totalProgress}</p>
<Dashboard id="dashboard" uppy={uppy} />
</>
);
}

export default function App() {
// keeping the uppy instance alive above the pages the user can switch during uploading
const [uppy] = useState(() => new Uppy());

return (
// Add your router here
<>
<Page1 />
<Page2 uppy={uppy} />
</>
);
}

Example: updating Uppy’s options dynamically based on props

// ...
function Component(props) {
// IMPORTANT: passing an initializer function to prevent the state from recreating.
const [uppy] = useState(() => new Uppy().use(Webcam));

useEffect(() => {
uppy.setOptions({ restrictions: props.restrictions });
}, [props.restrictions]);

useEffect(() => {
uppy.getPlugin('Webcam').setOptions({ modes: props.webcamModes });
}, [props.webcamModes]);

return <Dashboard uppy={uppy} plugins={['Webcam']} />;
}

Example: dynamic params and signature for Transloadit

When you go to production always make sure to set the signature. Not using Signature Authentication can be a security risk. Signature Authentication is a security measure that can prevent outsiders from tampering with your Assembly Instructions.

Generating a signature should be done on the server to avoid leaking secrets. In React, this could get awkward with a fetch in a useEffect and setting it to useState. Instead, it’s easier to use the assemblyOptions option to fetch the params.

// ...
function createUppy(userId) {
return new Uppy({ meta: { userId } }).use(Transloadit, {
async assemblyOptions(file) {
// You can send meta data along for use in your template.
// https://transloadit.com/docs/topics/assembly-instructions/#form-fields-in-instructions
const body = JSON.stringify({ userId: file.meta.userId });
const res = await fetch('/transloadit-params', { method: 'POST', body });
return response.json();
},
});
}

function Component({ userId }) {
// IMPORTANT: passing an initializer function to prevent Uppy from being reinstantiated on every render.
const [uppy] = useState(() => createUppy(userId));

useEffect(() => {
if (userId) {
// Adding to global `meta` will add it to every file.
uppy.setOptions({ meta: { userId } });
}
}, [uppy, userId]);
}