How can I save file from external url Laravel public directory
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# How Can I Save Files from External URLs into the Laravel Public Directory?
As a senior developer working with frameworks like Laravel, we frequently encounter scenarios where we need to ingest external content—like images, videos, or documents from an external URL—and make that content accessible within our application. The challenge often lies not just in downloading the data, but in correctly placing and configuring the file system operations so that it is publicly accessible via the web.
You mentioned trying to use `Storage::put()` but ending up saving the file in the `storage` folder instead of the desired `public` directory. This is a very common point of confusion, stemming from how Laravel manages its default storage disks. Let’s break down why this happens and detail the correct, robust way to achieve your goal.
## Understanding Laravel Storage Disks
Laravel's `Storage` facade abstracts file operations by allowing you to define "disks." By default, Laravel configures the `local` disk (which is what `Storage::put()` often defaults to) to point to the `storage/app/` directory. This separation is intentional: the `storage` directory is intended for private application data, logs, and uploads that are *not* meant to be directly served by the web server.
If you want a file to be accessible via a URL (i.e., served publicly), it must reside within the `public` directory. Trying to use standard storage methods on this directory can lead to permission issues or incorrect routing if your web server isn't explicitly configured for that path.
## The Correct Approach: Downloading and Storing Publicly
To successfully download an external file and place it into the Laravel `public` folder, you need a multi-step process: fetching the raw content and then manually writing that content to the public file system location. This bypasses the default configuration of the `Storage` facade for this specific operation.
### Step 1: Fetching the External Content
First, you need an HTTP client to download the file content. The standard Laravel way is often leveraging Guzzle, which is easily accessible within your framework context.
```php
use Illuminate\Support\Facades\Http;
$externalUrl = 'https://example.com/path/to/your/image.jpg';
try {
// Fetch the raw binary content of the file
$response = Http::get($externalUrl);
if ($response->successful()) {
$fileContents = $response->body();
} else {
throw new \Exception("Failed to download file. Status: " . $response->status());
}
} catch (\Exception $e) {
// Handle error appropriately
return response()->json(['error' => 'Download failed'], 500);
}
```
### Step 2: Saving the Content to the Public Directory
Once you have the raw binary data (`$fileContents`), you must use standard PHP file functions (like `file_put_contents`) or Laravel’s `Illuminate\Support\Facades\File` facade to write this content directly into your `public` folder.
Crucially, you need to define a path within the public directory where the file will live. For example, if you want the file accessible at `/images/external/my_image.jpg`, you must ensure the directory structure exists first.
```php
use Illuminate\Support\Facades\File;
$fileName = 'downloaded_image.jpg';
$publicDirectory = public_path('images/external'); // Define the target path
// Ensure the directory exists before writing the file
if (!File::exists($publicDirectory)) {
File::makeDirectory($publicDirectory);
}
$filePath = $publicDirectory . '/' . $fileName;
// Write the downloaded content to the public folder
if (File::put($filePath, $fileContents)) {
// File successfully saved in public/images/external/downloaded_image.jpg
return response()->json(['message' => 'File saved successfully!']);
} else {
throw new \Exception("Failed to write file to disk.");
}
```
## Best Practices for External File Handling
When dealing with external media, keep the following best practices in mind:
1. **Error Handling:** Always wrap HTTP requests and file operations in `try-catch` blocks. Network failures or permission issues are common when fetching external resources.
2. **Sanitization:** Never trust external data implicitly. If you are saving user-provided files, ensure you validate the MIME type and sanitize the filename before writing it to