uppy/docs/uploader/tus.mdx
2024-04-16 15:24:58 +02:00

308 lines
9.1 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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 lets 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 dont 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 its 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 its 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 dont 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 lets 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