How can I save file from external url Laravel public directory

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company
# 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