123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- ---
- 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/' });
- ```
- ### TypeScript
- If you want the `response` argument on the `upload-success` event and
- `file.response.body` to be typed, you have to pass a generic to the Uppy class.
- ```ts showLineNumbers
- // ...
- import Tus, { type TusBody } from '@uppy/tus';
- type MyMeta = {
- /* your added meta data */
- };
- const uppy = new Uppy<MyMeta, TusBody>().use(Tus, {
- endpoint: 'https://tusd.tusdemo.net/files/',
- });
- const [firstFile] = uppy.getFiles();
- // Correctly typed as XMLHttpRequest.
- // Populated after uppy.upload()
- firstFile.response.body.xhr;
- ```
- ## 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 it to `false` to not send any fields (or an empty array).
- - Set it to `['name']` to only send the `name` field.
- - Set it to `true` (the default) to send _all_ metadata 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
|