How can I get the full URL of file uploaded to s3 with Laravel?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
How Can I Get the Full S3 URL of a File Uploaded via Laravel?
Uploading files to cloud storage solutions like Amazon S3 is a common practice in modern web applications. When integrating Laravel with AWS S3, developers often face a subtle but crucial challenge: retrieving the correct, publicly accessible URL for the uploaded asset. The standard methods provided by the Storage facade sometimes return relative paths rather than the absolute public S3 object links you require.
This post will dive deep into why this happens and provide a robust solution to reliably generate the full S3 URLs for your stored files in Laravel applications.
The Challenge with Storage::url()
You are working with file paths that look like /datasheets/filename.jpeg. When you use methods like Storage::disk('s3')->url($path), Laravel, by default, generates a URL based on the configured disk structure. This results in relative paths, such as /datasheets/6GcfzgUPrA.jpeg, which is useful within the application but completely useless for direct external linking to the S3 bucket endpoint.
Your goal is to transform this relative path into an absolute URL format like https://s3.REGION.amazonaws.com/BUCKET-NAME/FULL-IMAGE-PATH. Concatenating the region and bucket name manually is brittle, as these details are dynamic and stored in your configuration.
The Solution: Leveraging S3 Configuration for Absolute URLs
To achieve the desired absolute S3 URL, you must bypass the default relative path generation and construct the URL using the specific configuration values that define your S3 bucket and region. While there isn't a single magic method on the Storage facade to do this universally across all disk types, we can access the underlying connection details to achieve this goal cleanly.
The most reliable approach involves accessing the S3 configuration directly within your service layer or controller logic. This ensures that the resulting URL is fully qualified and correct, adhering to best practices for external asset delivery, much like how you manage other services in a Laravel application (referencing principles found on laravelcompany.com).
Refactoring the Upload Logic
Let's refactor your provided example to correctly generate the full S3 URL. We will assume you have access to your bucket name and region, which are defined in your config/filesystems.php file under the disks configuration for the S3 driver.
Here is how you can modify your code block:
use Illuminate\Support\Facades\Storage;
// ... assuming $image variable holds the base64 data and $fullImagePath is '/datasheets/filename.jpeg'
$image = $picture;
$ext = explode(";", explode("/",explode(",", $image)[0])[1])[0];
$image = str_replace('data:image/'.$ext.';base64,', '', $image);
$image = str_replace(' ', '+', $image);
$imageName = str_random(10) . '.' . $ext;
$fullImagePath = 'datasheets/' . $imageName;
// 1. Upload the file content to S3
Storage::disk('s3')->put($fullImagePath, base64_decode($image));
// 2. Construct the Full S3 URL dynamically
$disk = Storage::disk('s3');
$bucket = config('filesystems.disks.s3.bucket'); // Dynamically get the bucket name
$region = config('filesystems.disks.s3.region'); // Dynamically get the region
// Construct the S3 URL using the path stored in Laravel and the dynamic configuration
$fullS3Url = "https://{$region}.amazonaws.com/{$bucket}/{$fullImagePath}";
$DataSheetPicture = new DataSheetPicture();
$DataSheetPicture->data_sheet_id = $DataSheet->id;
// Assign the newly constructed, absolute URL
$DataSheetPicture->picture = $fullS3Url;
$DataSheetPicture->save();
Explanation of the Improvement
Instead of relying on Storage::disk('s3')->url($path), we manually construct the URL. We retrieve the bucket name and region directly from the Laravel configuration (config/filesystems.php). By combining these dynamic values with the file path stored in your application ($fullImagePath), you generate the exact, publicly accessible S3 link required: https://s3.REGION.amazonaws.com/BUCKET-NAME/FULL-IMAGE-PATH.
This method is superior because it decouples your application logic from the specifics of how Laravel internally formats relative paths, giving you full control over the final asset delivery URL. This practice of accessing configuration for dynamic endpoint generation is fundamental to writing scalable and maintainable code in Laravel.
Conclusion
When dealing with cloud storage integrations like AWS S3 within a Laravel environment, always anticipate that default utility methods might return relative paths. For generating external, absolute URLs, developers must take the initiative to pull necessary metadata (like bucket names and regions) from the configuration files and construct the final URL manually. By adopting this approach, you ensure your application delivers correct, publicly accessible links every time, leading to a more robust and professional solution.