mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-23 10:18:40 +00:00
308 lines
9.1 KiB
Text
308 lines
9.1 KiB
Text
---
|
||
sidebar_position: 2
|
||
slug: /tus
|
||
---
|
||
|
||
import Tabs from '@theme/Tabs';
|
||
import TabItem from '@theme/TabItem';
|
||
import UppyCdnExample from '/src/components/UppyCdnExample';
|
||
|
||
# Tus
|
||
|
||
The `@uppy/tus` plugin brings resumable file uploading with [Tus](http://tus.io)
|
||
to Uppy by wrapping the [`tus-js-client`][].
|
||
|
||
## When should I use it?
|
||
|
||
:::tip
|
||
|
||
Not sure which uploader is best for you? Read
|
||
“[Choosing the uploader you need](/docs/guides/choosing-uploader)”.
|
||
|
||
:::
|
||
|
||
[Tus][tus] is an open protocol for resumable uploads built on HTTP. This means
|
||
accidentally closing your tab or losing connection let’s you continue, for
|
||
instance, your 10GB upload instead of starting all over.
|
||
|
||
Tus supports any language, any platform, and any network. It requires a client
|
||
and server integration to work. You can checkout the client and server
|
||
[implementations][] to find the server in your preferred language. You can store
|
||
files on the Tus server itself, but you can also use service integrations (such
|
||
as S3) to store files externally. If you don’t want to host your own server, see
|
||
“[Are there hosted Tus servers?](#are-there-hosted-tus-servers)”.
|
||
|
||
If you want reliable, resumable uploads: use `@uppy/tus` to connect to your Tus
|
||
server in a few lines of code.
|
||
|
||
## Install
|
||
|
||
<Tabs>
|
||
<TabItem value="npm" label="NPM" default>
|
||
|
||
```shell
|
||
npm install @uppy/tus
|
||
```
|
||
|
||
</TabItem>
|
||
|
||
<TabItem value="yarn" label="Yarn">
|
||
|
||
```shell
|
||
yarn add @uppy/tus
|
||
```
|
||
|
||
</TabItem>
|
||
|
||
<TabItem value="cdn" label="CDN">
|
||
<UppyCdnExample>
|
||
{`
|
||
import { Uppy, Tus } from "{{UPPY_JS_URL}}"
|
||
new Uppy().use(Tus, { endpoint: 'https://tusd.tusdemo.net/files' })
|
||
`}
|
||
</UppyCdnExample>
|
||
</TabItem>
|
||
</Tabs>
|
||
|
||
## Use
|
||
|
||
A quick overview of the complete API.
|
||
|
||
```js {10} showLineNumbers
|
||
import Uppy from '@uppy/core';
|
||
import Dashboard from '@uppy/dashboard';
|
||
import Tus from '@uppy/tus';
|
||
|
||
import '@uppy/core/dist/style.min.css';
|
||
import '@uppy/dashboard/dist/style.min.css';
|
||
|
||
new Uppy()
|
||
.use(Dashboard, { inline: true, target: 'body' })
|
||
.use(Tus, { endpoint: 'https://tusd.tusdemo.net/files/' });
|
||
```
|
||
|
||
## API
|
||
|
||
### Options
|
||
|
||
:::info
|
||
|
||
All options are passed to `tus-js-client` and we document the ones here that are
|
||
required, added, or changed. This means you can also pass functions like
|
||
[`onAfterResponse`](https://github.com/tus/tus-js-client/blob/master/docs/api.md#onafterresponse).
|
||
|
||
We recommended taking a look at the
|
||
[API reference](https://github.com/tus/tus-js-client/blob/master/docs/api.md)
|
||
from `tus-js-client` to know what is supported.
|
||
|
||
:::
|
||
|
||
#### `id`
|
||
|
||
A unique identifier for this plugin (`string`, default: `'Tus'`).
|
||
|
||
#### `endpoint`
|
||
|
||
URL of the tus server (`string`, default: `null`).
|
||
|
||
#### `headers`
|
||
|
||
An object or function returning an object with HTTP headers to send along
|
||
requests (`object | function`, default: `null`).
|
||
|
||
Keys are header names, values are header values.
|
||
|
||
```js
|
||
const headers = {
|
||
authorization: `Bearer ${window.getCurrentUserToken()}`,
|
||
};
|
||
```
|
||
|
||
Header values can also be derived from file data by providing a function. The
|
||
function receives an [Uppy file][] and must return an object where the keys are
|
||
header names, and values are header values.
|
||
|
||
```js
|
||
const headers = (file) => {
|
||
return {
|
||
authorization: `Bearer ${window.getCurrentUserToken()}`,
|
||
expires: file.meta.expires,
|
||
};
|
||
};
|
||
```
|
||
|
||
#### `chunkSize`
|
||
|
||
A number indicating the maximum size of a `PATCH` request body in bytes
|
||
(`number`, default: `Infinity`). Note that this option only affects local
|
||
browser uploads. If you need a max chunk size for remote (Companion) uploads,
|
||
you must set the `chunkSize` Companion option as well.
|
||
|
||
:::caution
|
||
|
||
Do not set this value unless you are forced to. The two valid reasons are
|
||
described in the
|
||
[`tus-js-client` docs](https://github.com/tus/tus-js-client/blob/master/docs/api.md#chunksize).
|
||
|
||
:::
|
||
|
||
#### `withCredentials`
|
||
|
||
Configure the requests to send Cookies using the
|
||
[`xhr.withCredentials`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials)
|
||
property (`boolean`, default: `false`).
|
||
|
||
The remote server must accept CORS and credentials.
|
||
|
||
#### `retryDelays`
|
||
|
||
When uploading a chunk fails, automatically try again after the defined
|
||
millisecond intervals (`Array<number>`, default: `[0, 1000, 3000, 5000]`).
|
||
|
||
By default, we first retry instantly; if that fails, we retry after 1 second; if
|
||
that fails, we retry after 3 seconds, etc.
|
||
|
||
Set to `null` to disable automatic retries, and fail instantly if any chunk
|
||
fails to upload.
|
||
|
||
#### `onBeforeRequest(req, file)`
|
||
|
||
Behaves like the
|
||
[`onBeforeRequest`](https://github.com/tus/tus-js-client/blob/master/docs/api.md#onbeforerequest)
|
||
function from `tus-js-client` but with the added `file` argument.
|
||
|
||
#### `onShouldRetry: (err, retryAttempt, options, next)`
|
||
|
||
When an upload fails `onShouldRetry` is called with the error and the default
|
||
retry logic as the last argument (`function`).
|
||
|
||
The default retry logic is an
|
||
[exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff)
|
||
algorithm triggered on HTTP 429 (Too Many Requests) errors. Meaning if your
|
||
server (or proxy) returns HTTP 429 because it’s being overloaded, @uppy/tus will
|
||
find the ideal sweet spot to keep uploading without overloading.
|
||
|
||
If you want to extend this functionality, for instance to retry on unauthorized
|
||
requests (to retrieve a new authentication token):
|
||
|
||
```js
|
||
import Uppy from '@uppy/core';
|
||
import Tus from '@uppy/tus';
|
||
new Uppy().use(Tus, {
|
||
endpoint: '',
|
||
async onBeforeRequest(req) {
|
||
const token = await getAuthToken();
|
||
req.setHeader('Authorization', `Bearer ${token}`);
|
||
},
|
||
onShouldRetry(err, retryAttempt, options, next) {
|
||
if (err?.originalResponse?.getStatus() === 401) {
|
||
return true;
|
||
}
|
||
return next(err);
|
||
},
|
||
async onAfterResponse(req, res) {
|
||
if (res.getStatus() === 401) {
|
||
await refreshAuthToken();
|
||
}
|
||
},
|
||
});
|
||
```
|
||
|
||
#### `allowedMetaFields`
|
||
|
||
Pass an array of field names to limit the metadata fields that will be added to
|
||
uploads as
|
||
[Tus Metadata](https://tus.io/protocols/resumable-upload.html#upload-metadata)
|
||
(`Array`, default: `null`).
|
||
|
||
- Set this to `['name']` to only send the `name` field.
|
||
- Set this to `null` (the default) to send _all_ metadata fields.
|
||
- Set this to an empty array `[]` to not send any fields.
|
||
|
||
#### `limit`
|
||
|
||
Limit the amount of uploads going on at the same time (`number`, default: `20`).
|
||
|
||
Setting this to `0` means no limit on concurrent uploads (not recommended).
|
||
|
||
## Frequently Asked Questions
|
||
|
||
:::info
|
||
|
||
The Tus website has extensive [FAQ section](https://tus.io/faq.html), we
|
||
recommend taking a look there as well if something is unclear.
|
||
|
||
:::
|
||
|
||
### How is file meta data stored?
|
||
|
||
Tus uses unique identifiers for the file names to prevent naming collisions. To
|
||
still keep the meta data in place, Tus also uploads an extra `.info` file with
|
||
the original file name and other meta data:
|
||
|
||
```json
|
||
{
|
||
"ID": "00007a99d16d4eeb5a3e3c080b6f69da+JHZavdqPSK4VMtarg2yYcNiP8t_kDjN51lBYMJdEyr_wqEotVl8ZBRBSTnWKWenZBwHvbLNz5tQXYp2N7Vdol.04ysQAuw__suTJ4IsCljj0rjyWA6LvV4IwF5P2oom2",
|
||
"Size": 1679852,
|
||
"SizeIsDeferred": false,
|
||
"Offset": 0,
|
||
"MetaData": {
|
||
"filename": "cat.jpg",
|
||
"filetype": "image/jpeg"
|
||
},
|
||
"IsPartial": false,
|
||
"IsFinal": false,
|
||
"PartialUploads": null,
|
||
"Storage": {
|
||
"Bucket": "your-bucket",
|
||
"Key": "some-key",
|
||
"Type": "s3store"
|
||
}
|
||
}
|
||
```
|
||
|
||
### How do I change files before sending them?
|
||
|
||
If you want to change the file names, you want to do that in
|
||
[`onBeforeFileAdded`](/docs/uppy#onbeforefileaddedfile-files).
|
||
|
||
If you want to send extra headers with the request, use [`headers`](#headers) or
|
||
[`onBeforeRequest`](#onbeforerequestreq-file).
|
||
|
||
### How do I change (or move) files after sending them?
|
||
|
||
If you want to preserve files names, extract meta data, or move files to a
|
||
different place you generally can with hooks or events. It depends on the Tus
|
||
server you use how it’s done exactly. [`tusd`][], for instance, exposes
|
||
[hooks](https://github.com/tus/tusd/blob/master/docs/hooks.md) and
|
||
[`tus-node-server`](https://github.com/tus/tus-node-server) has
|
||
[events](https://github.com/tus/tus-node-server#events).
|
||
|
||
### Which server do you recommend?
|
||
|
||
[Transloadit](https://transloadit.com) runs [`tusd`][] in production, where it
|
||
serves millions of requests globally. So we recommend `tusd` as battle-tested
|
||
from our side, but other companies have had success with other
|
||
[implementations][] so it depends on your needs.
|
||
|
||
### Are there hosted Tus servers?
|
||
|
||
All [Transloadit plans](https://transloadit.com/pricing) come with a hosted
|
||
[`tusd`][] server. You don’t have to do anything to leverage it, using
|
||
[`@uppy/transloadit`](/docs/transloadit) automatically uses Tus under the hood.
|
||
|
||
### Why Tus instead of directly uploading to AWS S3?
|
||
|
||
First: reliable, resumable uploads. This means accidentally closing your tab or
|
||
losing connection let’s you continue, for instance, your 10GB upload instead of
|
||
starting all over.
|
||
|
||
Tus is also efficient with lots of files (such as 8K) and large files. Uploading
|
||
to AWS S3 directly from the client also introduces quite a bit of overhead, as
|
||
more requests are needed for the flow to work.
|
||
|
||
[`tus-js-client`]: https://github.com/tus/tus-js-client
|
||
[uppy file]: /docs/uppy#working-with-uppy-files
|
||
[tus]: https://tus.io/
|
||
[`tusd`]: https://github.com/tus/tusd
|
||
[implementations]: https://tus.io/implementations.html
|