earmsby's avatar

FileUpload field on Filament infolist

I have a Filament form with this upload field:

FileUpload::make('contract_pdf')
               ->disk('public')
               ->directory('contract_pdfs')
                ->maxSize(200000)
               ->visibility('public')

I set up the symlink using php artisan storage:link and that seems to be working just fine.

My infolist for this field is:

TextEntry::make('contract_pdf')
               ->url(fn ($record)=> $record->contract_pdf)
                ->openUrlInNewTab()
                ->inlineLabel(),

The link is mostly correct and opens in a new tab as expected but the link is: http://myURL/contracts/contract_pdfs/01KHS8DGGNZP2J6MV7C38012AK.pdf instead of: http://myURL/contract_pdfs/01KHS8DGGNZP2J6MV7C38012AK.pdf

If I manually change the url and take out the "contracts", I can view the file.

The url of the infolist is: http://myURL/contracts/55 So, I can see that it's using a relative link instead of an absolute one. Is there a way to set this?

0 likes
3 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

Certainly! The issue here is that you're using a relative path as the file URL, so Filament is treating it as relative to the current page (which is at /contracts/55), resulting in a link like /contracts/contract_pdfs/....

Instead, you should generate an absolute URL to your file. The best practice is to use Laravel's Storage::url() method, which will produce a URL relative to your public disk and will honor your storage:link configuration.

Here’s how you can fix your code:

use Illuminate\Support\Facades\Storage;

// ...

TextEntry::make('contract_pdf')
    ->url(fn ($record) => $record->contract_pdf 
        ? Storage::disk('public')->url($record->contract_pdf) 
        : null)
    ->openUrlInNewTab()
    ->inlineLabel(),

Explanation:

  • Storage::disk('public')->url($record->contract_pdf) will generate a URL like /storage/contract_pdfs/filename.pdf, which is correct if you’re storing in the public disk and used the default storage symlink setup.
  • The check for ? $record->contract_pdf : null ensures you don't get a URL if there's no file.

Bonus: If, for any reason, you want to display just the file name (not the path), you can use:

TextEntry::make('contract_pdf')
    ->label('Contract PDF')
    ->url(fn ($record) => $record->contract_pdf 
        ? Storage::disk('public')->url($record->contract_pdf) 
        : null)
    ->display(fn ($record) => basename($record->contract_pdf))
    ->openUrlInNewTab()
    ->inlineLabel(),

Summary:
Always use Storage::url() to generate file URLs for files managed by Laravel's storage system. This guarantees you get the right, absolute URL every time.

Let me know if you have further questions!

1 like
Glukinho's avatar

What value is actually in contract_pdf column in database table?

earmsby's avatar

the value is like "contract_pdfs/01KHS8DGGNZP2J6MV7C38012AK.pdf

The solution above did the trick.

Please or to participate in this conversation.