Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jehoshaphatbc's avatar

Misplacement of Laravel Livewire Tenancy File Uploads into Central Storage Instead of Tenant-Specific Storage

Issue Description: During the file upload process in Laravel Livewire Tenancy, files intended for temporary or tenant-specific storage seem to be directed incorrectly towards the central storage or primary storage. This results in an issue where files, despite being uploaded for temporary storage, are not correctly placed within the designated tenant's storage. Consequently, when accessed, these files appear empty or inaccessible, possibly due to residing in the Livewire tmp storage for the wrong or unspecified tenant.

Steps to Reproduce: Initiate file upload process within Laravel Livewire Tenancy. Observe the direction of file storage during temporary storage phases. Attempt to access the temporarily stored files from the tenant's perspective.

Expected Behavior: Files uploaded for temporary storage should be directed and accessible within the Livewire tmp storage specific to the corresponding tenant. Retrieval of files from temporary storage should yield the expected content without being empty or inaccessible.

Actual Behavior: Files uploaded for temporary storage appear to be misplaced and possibly stored in central storage or the wrong tenant's storage. Upon access, these files are either empty or cannot be retrieved, leading to accessibility issues.

0 likes
6 replies
Snapey's avatar

whatever it is doing is under the instruction of your code

paulpapara's avatar

I've had exactly the same issue as you've described, I'm using stancl/tenancy in a Filament v3 project (using Livewire v3). What I did was the following:

First, make sure you have enabled universal routes and followed the steps for real-time facades:

https://tenancyforlaravel.com/docs/v3/features/universal-routes https://tenancyforlaravel.com/docs/v3/realtime-facades

The below steps A and B are from here: https://tenancyforlaravel.com/docs/v3/integrations/livewire/

A. In a service provider (AppServiceProvider for me), add the following to the boot() function:

public function boot(): void
{
    // ...

    Livewire::setUpdateRoute(function ($handle) {
        return \Illuminate\Support\Facades\Route::post('/livewire/update', $handle)
            ->middleware(
                'web',
                'universal',
                InitializeTenancyByDomain::class, // or whatever tenancy middleware you use
            );
    });

    FilePreviewController::$middleware = ['web', 'universal', InitializeTenancyByDomain::class];
}

B. In the Livewire config file (which you have to publish yourself in case you haven't done that already) I have modified the middleware field of the temporary_file_upload section to include the tenancy initialization middleware and universal routes:

'temporary_file_upload' => [
// ...
	'middleware' => ['throttle:60,1', 'universal', InitializeTenancyByDomain::class],
// ...
]

C. Then, I had to create a new filesystem tenancy bootstrapper, in which I have copied the contents of FilesystemTenancyBootstrapper (that comes bundled with the stancl/tenancy package) and added the following lines to the bootstrap() function, in order to overwrite the public disk's url property, as I was using (and having issues) with the public disk:

    public function bootstrap(Tenant $tenant)
    {
        foreach ($this->app['config']['tenancy.filesystem.disks'] as $disk) {
            // ...

            if ($disk === 'public') {
                $this->app['config']["filesystems.disks.public.url"] = 'http://'.parse_url(url()->current())['host'].'/tenancy/assets';
            }
        }
    }

You'll have to make sure that you're registering this new filesystem bootstrapper in the tenancy config file, under the 'bootstrappers' section and also don't forget to remove the old one.

1 like
Alberto Escamilla's avatar

@paulpapara Hello friend, I have the same problem, you already perform step A and B but I don't understand step C well, is this boot file a driver? Model?

Samuraiflamesf's avatar

Hello, in step C, what I did and it worked now:

Create the file in \app\Tenancy\Bootstrappers\CustomFilesystemTenancyBootstrapper.php with all the code provided:

<?php

namespace App\Tenancy\Bootstrappers;

use Stancl\Tenancy\Contracts\Tenant;
use Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper as BaseFilesystemTenancyBootstrapper;

class CustomFilesystemTenancyBootstrapper extends BaseFilesystemTenancyBootstrapper
{
    public function bootstrap(Tenant $tenant)
    {
        parent::bootstrap($tenant); // Mantém o comportamento padrão

        foreach ($this->app['config']['tenancy.filesystem.disks'] as $disk) {
            if ($disk === 'public') {
                // Ajusta a URL para o disco público
                $this->app['config']["filesystems.disks.public.url"] =
                    'h t t p://' . parse_url(url()->current())['host'] . '/tenancy/assets';
            }
        }
    }
}

  1. Go to Config/tenancy.php and replace:
'bootstrappers' => [
        Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper::class,
        Stancl\Tenancy\Bootstrappers\CacheTenancyBootstrapper::class,
        // Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper::class,
        Stancl\Tenancy\Bootstrappers\QueueTenancyBootstrapper::class,
        App\Tenancy\Bootstrappers\CustomFilesystemTenancyBootstrapper::class,
        // Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper::class, // Note: phpredis is needed
    ],
Fzoltan87's avatar

Hello. I was struggling with the same issue (Laravel 12 + Filament 3 + Livewire 3 + stancl/tenancy 3.9). Thank you so much for this short guide — now I’m able to upload files from the tenant’s Filament panel as well.

However, this is how my folder structure looks:

When using the central domain, uploads go here (which I assume is totally fine):

  • storage/app/livewire-tmp

  • storage/app/public

When using the tenant domain, uploads go here (which I also assume is fine — each tenant domain gets its own separate folder inside storage):

  • storage/tenant/app/livewire-tmp

  • storage/tenant/app/public

The problem is: in the tenant Filament form, the SpatieMediaLibraryFileUpload component does not read the uploaded files from storage/tenant/app/public.

How could I fix this?

Please or to participate in this conversation.