IMPLEMENTING RESUMABLE FILE UPLOADS IN PHP WITH LARAVEL 8, UPPY AND TUS
Tags: laravel, tus, uppy, tutorial
Published: 2022-06-30 20:04:29

The following guide helps you to implement a little fancier file uploads for your web apps

**Requirements**

[Laravel](https://laravel.com/): Laravel is a web application framework with expressive, elegant syntax. Supported versions > 5.x.x . The version used in this guide is Laravel 8.

[Uppy](https://uppy.io/): Sleek, modular open source JavaScript file uploader.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/poa12re28u3rxllnj83b.JPG)

[Tus](https://tus.io/): Open Protocol for Resumable File Uploads.

[Tus-PHP](https://github.com/ankitpokhrel/tus-php):  A pure PHP server and client for the tus resumable upload protocol v1.0.0.

[Redis](https://redis.io/): An open source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker.

**Tutorial**

1.Install Uppy and its supported plugins (Dashboard, Tus) with NPM.

```
npm install uppy

npm install @uppy/dashboard

npm install @uppy/tus

```

2. Create your file upload element in your blade file. In this example, we are using a button.

```
<button  type='button' class='btn btn-success btn-sm' id='file_upload' name='file_upload'>Upload File</button>

```
3.In order to post your file to your /tus endpoint, you need to add CSRF-TOKEN. Create a meta tag to hold your token in the blade.php which you will pass to your Uppy.js.

```
<meta name="csrf-token" content={"{ csrf_token() }}">
```

4.Create your Uppy configuration in your JavaScript file.

```
import Uppy from '@uppy/core';
import Tus from '@uppy/tus'
import Dashboard from '@uppy/dashboard';


const uppy = new Uppy({
    debug: false,
    autoProceed: false,
    restrictions: {
      maxFileSize: 1000000,
      maxNumberOfFiles: 1,
      allowedFileTypes: ['image/*'],
    }
})
.use(Dashboard, {
target: 'body',
  trigger: '#file_upload',
  closeAfterFinish: true,
  browserBackButtonClose: false,
  showProgressDetails: true,
})
.use(Tus, {
    endpoint: '/tus', // use your tus endpoint here
    retryDelays: [0, 1000, 3000, 5000],
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
})
```

5. We need Redis for cache management. Go ahead and follow the [guide](https://redis.io/docs/getting-started/installation/) for installing Redis on your system. If you’re running a Windows system you need to install Windows Subsystem for Linux before you begin. I will recommend the Ubuntu distro.

```
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list

sudo apt-get update
sudo apt-get install redis
```

6. Start the Redis server

```
redis-server

```

7. Confirm that your redis server is running smoothly and can connect to it

```
redis-cli ping

```

8. We will now tie everything together with the Tus-PHP from Ankit Pokhrel. Add Tus-PHP with Composer

```
composer require ankitpokhrel/tus-php

```

9. Create a service provider (eg. TusServiceProvider) and add it to your config config/app.php.

```
php artisan make:provider TusServiceProvider

```

10. Update the provider with the sample code from the Laravel integration guide. You do not have to exclude the server endpoint from Laravel’s CSRF validation. That’s a security risk and has been taken care of by passing it in the headers. Also, remember to create your upload folder in the storage

```
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use TusPhp\Tus\Server as TusServer;


class TusServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
        $this->app->singleton('tus-server', function ($app) {
            $server = new TusServer('redis');

            $server->setApiPath('/tus');
            $server->setUploadDir(storage_path('app/public/uploads'));

            return $server;
        });

    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}
```

11. Add the /tus endpoint to your route to serve requests.

```
Route::any('/tus/{any?}', function () {
    return app('tus-server')->serve();
})->where('any', '.*');
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1a2mlbnx6y4rgnmsxso2.jpg)

That’s all folks. Users will be able to resume the upload of files after an network error or closing the browser. Hit the [comments](https://nkwaten.wordpress.com/2022/06/25/implementing-resumable-file-uploads-in-php-with-laravel-8-uppy-and-tus/) if you need any help.