How to use DigitalOcean Spaces with Laravel Voyager?
Tags: laravel, php, webdev, javascript
Published: 2023-07-30 08:11:50

# Introduction

DigitalOcean Spaces is an object storage service that allows you to store and serve large amounts of data. It is a reliable and flexible solution for developers, especially when integrated with Laravel Voyager - a Laravel package that provides an admin interface with BREAD (Browse, Read, Edit, Add, Delete) operations, media manager, menu builder, and much more.

This tutorial will guide you step-by-step on how to integrate DigitalOcean Spaces with Laravel Voyager.

Before we begin, ensure you have a working Laravel application with Voyager installed. We're also assuming that you have already created your DigitalOcean Space and have the necessary credentials: `Spaces Key`, `Spaces Secret`, `Spaces region`, `Spaces Bucket` and `Spaces endpoint`.

# Laravel Filesystem

Laravel provides a clean, simple API over the popular Flysystem PHP package by Frank de Jonge. The Laravel Flysystem integration provides simple to use drivers for working with local filesystems, Amazon S3, and even FTP servers. To utilize this feature for our purpose, we need to install a specific package.

# Step 1: Installing the `flysystem-aws-s3-v3` Package

The DigitalOcean Spaces is compatible with the Amazon S3 API. So, we will use the `flysystem-aws-s3-v3` package to interact with the DigitalOcean Spaces.

Open your terminal and navigate to the root directory of your Laravel project. Now, run the following command:

```
composer require league/flysystem-aws-s3-v3
```

This command will install the `flysystem-aws-s3-v3` package which will allow us to interact with the DigitalOcean Spaces.

# Step 2: Configuring the File System

In the root directory of your Laravel application, open the `config/filesystems.php` file. Here, we will add a new disk definition for 'spaces':

```
'spaces' => [
    'driver' => 's3',
    'key' => env('DO_SPACES_KEY'),
    'secret' => env('DO_SPACES_SECRET'),
    'region' => env('DO_SPACES_REGION'),
    'bucket' => env('DO_SPACES_BUCKET'),
    'endpoint' => env('DO_SPACES_ENDPOINT'),
    'visibility' => 'public',
],
```

The `'visibility' => 'public'` setting is needed to ensure that the images uploaded via the media manager are visible to the public.

Next, open the `.env` file and add the following lines:

```
DO_SPACES_KEY=your_spaces_key           # Example: 1234567890ABCDEF
DO_SPACES_SECRET=your_spaces_secret     # Example: 1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF
DO_SPACES_REGION=your_spaces_region     # Example: nyc3
DO_SPACES_BUCKET=your_spaces_bucket     # Example: my-bucket
DO_SPACES_ENDPOINT=your_spaces_endpoint # Example: https://nyc3.digitaloceanspaces.com
```

Note that we didn't add the bucket name to the endpoint. This is because the `flysystem-aws-s3-v3` package will automatically append the bucket name to the endpoint.

# Step 3: Configuring Voyager

Now, let's open the `config/voyager.php` file and update the storage disk to 'spaces':

```
'storage' => [
    'disk' => 'spaces',
],
```

# Step 4: Overriding Default Voyager Blade View (Optional)

In some older versions of Voyager, the media manager view had some issues with the file path.

To verify if you are still affected by this issue, visit the Voyager admin and if you see this error:

```
Found 1 error while validating the input provided for the GetObject operation: [Key] expected string length to be >= 1, but found string length of 0
```

The following steps will help you resolve this issue.

> NOTE: If you don't see the above error, you can skip this step.

First, create a new directory for the view:

```
mkdir -p resources/views/vendor/voyager/media
```

Next, copy the Voyager media manager view to your new directory:

```
cp vendor/tcg/voyager/resources/views/media/manager.blade.php resources/views/vendor/voyager/media
```

Finally, open the copied `manager.blade.php` file and update this line:

```
<div class="img_icon" :style="imgIcon('{{ Storage::disk(config('voyager.storage.disk'))->url('/') }}'+file)"></div>
```

To:

```
<div class="img_icon" :style="imgIcon('{{ Storage::disk(config('voyager.storage.disk'))->url('./') }}'+file)"></div>
```

Note that the only change is the addition of a `./` before the `file` variable.

# Conclusion

After completing these steps, your Laravel Voyager application should now be set up to use DigitalOcean Spaces for file storage. This integration unlocks new possibilities for you, allowing you to scale your applications efficiently.

As a next step, you can try to upload a file using the media manager and check if it is uploaded to your DigitalOcean Spaces bucket.

Happy coding!