melogail/nova-aws-file-manager

A Laravel Nova tool.

Maintainers

Package info

github.com/melogail/nova-aws-file-manager

Language:Vue

pkg:composer/melogail/nova-aws-file-manager

Statistics

Installs: 13

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-06-15 13:32 UTC

This package is auto-updated.

Last update: 2026-06-15 13:58:22 UTC


README

A Laravel Nova package that provides a full Amazon S3 file manager as a Nova sidebar tool, plus two reusable resource fields (AwsFileManagerDialogField and AwsFileManagerUploadField) for Nova resources.

All uploads are performed directly from the browser to S3 using presigned URLs (single PUT for small files, multipart for large files). File bytes never pass through PHP, so uploads of 1 GB, 2 GB, and larger (up to S3's 5 TB per-object limit) are fully supported.

Features

  • Sidebar tool – browse the bucket like a file explorer: navigate folders, create / rename / delete directories, rename / delete files, and upload via drag-and-drop or file picker with live progress.
  • Two resource fields, both styled to match Nova's native file upload field:
    • AwsFileManagerDialogField – a Browse files box that opens the full file manager in a modal so you can pick an existing object. Selecting a file populates the field value.
    • AwsFileManagerUploadField – a drag-and-drop / click dropzone that uploads a new file directly to S3 (no modal) into a configurable uploadPath, then stores the resulting key or URL.
    • Both render previews with image thumbnails, or PDF / video / audio / archive / document / code / generic icons by file type.
  • Direct-to-S3 multipart uploads – the server only signs requests; it never receives the uploaded bytes.

Installation

The package is published on Packagist, so you can install it with Composer:

composer require melogail/nova-aws-file-manager

Because Laravel Nova is a paid, private package, make sure your project is already authenticated against nova.laravel.com (your composer.json should contain the Nova Composer repository and you should have valid auth.json credentials) before running the command above.

The service provider is auto-discovered via the extra.laravel.providers entry, so no manual registration in config/app.php is required.

Publish the configuration file:

php artisan vendor:publish --tag=nova-aws-file-manager-config

The compiled front-end assets are shipped in the package's dist/ directory, so no asset build step is needed when consuming the package. (If you are developing the package locally, rebuild assets after JS/Vue changes with npm install && npm run prod from the package root.)

Configuration

Configuration lives in config/nova-aws-file-manager.php and is driven by environment variables. By default it reuses the application's s3 disk credentials.

NOVA_AWS_FM_DISK=s3
NOVA_AWS_FM_BUCKET="${AWS_BUCKET}"
NOVA_AWS_FM_REGION="${AWS_DEFAULT_REGION}"
NOVA_AWS_FM_PREFIX=
NOVA_AWS_FM_URL_STRATEGY=temporary   # temporary | public
NOVA_AWS_FM_PRESIGN_TTL=3600
Key Description
disk Laravel filesystem disk (driver s3) whose client is used.
bucket Target bucket (defaults to AWS_BUCKET).
region Target region (defaults to AWS_DEFAULT_REGION).
prefix Optional key prefix scoping the manager to a sub-path.
url_strategy temporary (signed URLs) or public (permanent object URLs).
presign_ttl Lifetime (seconds) of presigned upload/preview URLs.
multipart part_size, concurrency, and threshold for multipart uploads.

Registering the tool

Add the tool to the tools() method of your NovaServiceProvider:

use Melogail\NovaAwsFileManager\NovaAwsFileManager;

public function tools(): array
{
    return [
        // ...
        new NovaAwsFileManager,
    ];
}

Using the fields

The package ships two resource fields. Both share the same options and store the relative S3 key by default; call storeAsUrl() to store a resolvable URL instead.

AwsFileManagerDialogField (pick an existing file)

Renders a Nova-styled Browse files box that opens the file manager in a modal. Selecting a file populates the field value.

use Melogail\NovaAwsFileManager\Fields\AwsFileManagerDialogField;

public function fields(NovaRequest $request): array
{
    return [
        AwsFileManagerDialogField::make('Attachment'),

        // Store the full object URL instead of the relative key:
        AwsFileManagerDialogField::make('Brochure', 'brochure')->storeAsUrl(),

        // Restrict the picker to certain extensions:
        AwsFileManagerDialogField::make('Cover', 'cover_image')
            ->acceptedTypes(['jpg', 'jpeg', 'png', 'webp']),
    ];
}

AwsFileManagerUploadField (upload directly, no modal)

Renders a Nova-styled drag-and-drop / click dropzone that uploads the chosen file straight to S3 under the path given to uploadPath(), then stores the resulting key (or URL). No modal is opened.

use Melogail\NovaAwsFileManager\Fields\AwsFileManagerUploadField;

public function fields(NovaRequest $request): array
{
    return [
        // Uploads into "documents/brochures/<filename>":
        AwsFileManagerUploadField::make('Brochure', 'brochure')
            ->uploadPath('documents/brochures'),

        // Store the full object URL and restrict extensions:
        AwsFileManagerUploadField::make('Cover', 'cover_image')
            ->uploadPath('covers')
            ->acceptedTypes(['jpg', 'jpeg', 'png', 'webp'])
            ->storeAsUrl(),
    ];
}
Method Field(s) Description
uploadPath(string $path) Upload S3 prefix that uploaded files are stored under.
acceptedTypes(array $ext) Dialog & Upload Restrict selectable / uploadable extensions.
storeAsUrl(bool = true) Dialog & Upload Store a resolvable URL instead of the relative S3 key.

Required S3 bucket CORS policy

Because the browser uploads directly to S3, the bucket must allow cross-origin PUT/POST requests from your Nova domain and expose the ETag header (needed to complete multipart uploads):

[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
    "AllowedOrigins": ["https://your-nova-domain.test"],
    "ExposeHeaders": ["ETag"],
    "MaxAgeSeconds": 3000
  }
]

How uploads work

Browser                         Laravel (this package)            S3
  | POST /uploads/create  ----->  CreateMultipartUpload   ----->  |
  | <----------------------------- uploadId                       |
  | POST /uploads/sign    ----->  presigned UploadPart URLs       |
  | PUT part 1..n  ------------------------------------------->   |  (direct, no PHP)
  | <----------------------------- ETag per part (CORS)           |
  | POST /uploads/complete ---->  CompleteMultipartUpload ----->  |

Files below the configured multipart.threshold use a single presigned PUT instead. The JavaScript uploader sizes parts dynamically to stay within S3's 10,000-part limit, so arbitrarily large files upload correctly.

License

MIT