title: "Migration guides" type: docs permalink: docs/migration-guides order: 10
These cover all the major Uppy versions and how to migrate to them.
With 2.0, following in the footsteps of Microsoft, we are dropping support for IE11. As a result, we are able to remove all built-in polyfills, and the new bundle size is 25% smaller! If you want your app to still support older browsers (such as IE11), you may need to add the following polyfills to your bundle:
If you're using a bundler, you need import these before Uppy:
import 'core-js'
import 'whatwg-fetch'
import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'
// Order matters here: AbortController needs fetch, which needs Promise (provided by core-js).
import 'md-gum-polyfill'
import ResizeObserver from 'resize-observer-polyfill'
window.ResizeObserver ??= ResizeObserver
export { default } from '@uppy/core'
export * from '@uppy/core'
If you're using Uppy from a CDN, we now provide two bundles: one for up-to-date browsers that do not include polyfills and use modern syntax, and one for legacy browsers. When migrating, be mindful about the types of browsers you want to support:
<!-- Modern browsers (recommended) -->
<script src="https://releases.transloadit.com/uppy/v2.1.1/uppy.min.js"></script>
<!-- Legacy browsers (IE11+) -->
<script nomodule src="https://releases.transloadit.com/uppy/v2.1.1/uppy.legacy.min.js"></script>
<script type="module">import "https://releases.transloadit.com/uppy/v2.1.1/uppy.min.js";</script>
Please note that while you may be able to get 2.0 to work in IE11 this way, we do not officially support it anymore.
BasePlugin
or UIPlugin
instead of Plugin
@uppy/core
provided a Plugin
class for creating plugins. This was used for any official plugin, but also for users who want to create their own custom plugin. However, Plugin
always came bundled with Preact, even if the plugin itself didn't add any UI elements.
Plugin
has been replaced with BasePlugin
and UIPlugin
. BasePlugin
is the minimum you need to create a plugin and UIPlugin
adds Preact for rendering user interfaces.
You can import them from @uppy/core
:
import { BasePlugin, UIPlugin } from '@uppy/core'
Official plugins have already been upgraded. If you are using any custom plugins, upgrade Preact to the latest version. At the time of writing this is 10.5.13
.
Titles for plugins used to be set with the title
property in the plugin options, but all other strings are set in locale
. This has now been aligned. You should set your plugin title from the locale
property.
Before
import Webcam from '@uppy/webcam'
uppy.use(Webcam, {
title: 'Some title',
})
After
import Webcam from '@uppy/webcam'
uppy.use(Webcam, {
locale: {
strings: {
title: 'Some title',
},
},
})
new
keywordThe default export Uppy
is no longer callable as a function. This means you construct the Uppy
instance using the new
keyword.
import Uppy from '@uppy/core'
const uppy = new Uppy() // correct.
const otherUppy = Uppy() // incorrect, will throw.
allowMultipleUploads
to allowMultipleUploadBatches
allowMultipleUploadBatches
means allowing multiple calls to .upload()
, in other words, a user can add more files after already having uploaded some.
We have renamed this to be more intention revealing that this is about uploads, and not whether a user can choose multiple files for one upload.
const uppy = new Uppy({
allowMultipleUploadBatches: true,
})
@uppy/xhr-upload
and @uppy/tus
The default limit has been changed from 0
to 5
. Setting this to 0
means there is no limit on concurrent uploads.
You can change the limit on the Tus and XHR plugin options.
uppy.use(Tus, {
// ...
limit: 10,
})
uppy.use(XHRUpload, {
// ...
limit: 10,
})
Uppy used to have loose types by default and strict types as an opt-in. The default export was a function that returned the Uppy
class, and the types came bundled with the default export (Uppy.SomeType
).
import Uppy from '@uppy/core'
import Tus from '@uppy/tus'
const uppy = Uppy<Uppy.StrictTypes>()
uppy.use(Tus, {
invalidOption: null, // this will make the compilation fail!
})
Uppy is now strictly typed by default and loose types have been removed.
// ...
const uppy = new Uppy()
uppy.use(Tus, {
invalidOption: null, // this will make the compilation fail!
})
Uppy types are now individual exports and should be imported separately.
import type { PluginOptions, UIPlugin, PluginTarget } from '@uppy/core'
@uppy/core
provides an .on
method to listen to events. The types for these events were loose and allowed for invalid events to be passed, such as uppy.on('upload-errrOOOoooOOOOOrrrr')
.
// Before:
type Meta = { myCustomMetadata: string }
// Invalid event
uppy.on<Meta>('upload-errrOOOoooOOOOOrrrr', () => {
// ...
})
// After:
// Normal event signature
uppy.on('complete', (result) => {
const successResults = result.successful
})
// Custom signature
type Meta = { myCustomMetadata: string }
// Notice how the custom type has now become the second argument
uppy.on<'complete', Meta>('complete', (result) => {
// The passed type is now merged into the `meta` types.
const meta = result.successful[0].meta.myCustomMetadata
})
Plugins that add their own events can merge with existing ones in @uppy/core
with declare module '@uppy/core' { ... }
. This is a TypeScript pattern called module augmentation. For instance, when using @uppy/dashboard
:
uppy.on('dashboard:file-edit-state', (file) => {
const fileName = file.name
})
@uppy/aws-s3-multipart
See the Uppy 2.0.0 announcement post about the batch pre-signing URLs change.
prepareUploadPart
has been renamed to prepareUploadParts
(plural). See the documentation link on how to use this function.
.run
method from @uppy/core
The .run
method on the Uppy
instance has been removed. This method was already obsolete and only logged a warning. As of this major version, it no longer exists.
resume
and removeFingerprintOnSuccess
options from @uppy/tus
Tus will now by default try to resume uploads if the upload has been started in the past.
This also means tus will store some data in localStorage for each upload, which will automatically be removed on success. Making removeFingerprintOnSuccess
obsolete too.
Uppy 1.0 will continue to receive bug fixes for three more months (until ), security fixes for one more year (until ), but no more new features after today. Exceptions are unlikely, but can be made – to accommodate those with commercial support contracts, for example.
We hope you'll waste no time in taking Uppy 2.0 out for a walk. When you do, please let us know what you thought of it on Reddit, HN, ProductHunt, or Twitter. We're howling at the moon to hear from you!