Skip to main content

Laravel Pdfdrive -

To manage PDFs like a drive, you need a robust table. Here's a migration example:

Schema::create('pdf_documents', function (Blueprint $table) 
    $table->id();
    $table->foreignId('user_id')->constrained();
    $table->string('title');
    $table->string('filename');
    $table->string('disk')->default('local'); // local, s3, google_drive, dropbox
    $table->string('path');
    $table->string('mime_type')->default('application/pdf');
    $table->unsignedBigInteger('size')->nullable(); // in bytes
    $table->json('metadata')->nullable(); // Store custom data like invoice_id, report_date
    $table->string('share_token')->unique()->nullable(); // for public access
    $table->timestamp('expires_at')->nullable(); // for expiring links
    $table->timestamps();
    $table->softDeletes(); // enable trash feature
$table->index(['user_id', 'created_at']);
$table->index('share_token');

);

Create a corresponding Eloquent model:

class PDFDocument extends Model
use SoftDeletes;
protected $fillable = ['title', 'filename', 'disk', 'path', 'size', 'metadata', 'share_token', 'expires_at'];
protected $casts = ['metadata' => 'array', 'expires_at' => 'datetime'];
public function user()
return $this->belongsTo(User::class);
public function getUrlAttribute(): string
return Storage::disk($this->disk)->url($this->path);
public function getTemporaryUrl($expiresInMinutes = 15): string
return Storage::disk($this->disk)->temporaryUrl($this->path, now()->addMinutes($expiresInMinutes));


public function index()
$documents = PDFDocument::where('user_id', auth()->id())
        ->latest()
        ->paginate(20);
    return view('pdfdrive.index', compact('documents'));

public function download(PDFDocument $pdf) $this->authorize('view', $pdf); // using policies laravel pdfdrive

return Storage::disk($pdf->disk)->download($pdf->path, $pdf->filename);

public function stream(PDFDocument $pdf) return Storage::disk($pdf->disk)->response($pdf->path);

public function share($token) $pdf = PDFDocument::where('share_token', $token) ->where('expires_at', '>', now()) ->firstOrFail();

return Storage::disk($pdf->disk)->response($pdf->path);

public function destroy(PDFDocument $pdf) $this->authorize('delete', $pdf); Storage::disk($pdf->disk)->delete($pdf->path); $pdf->delete();

return back()->with('success', 'PDF deleted from drive.');

Routes:

Route::middleware('auth')->group(function () 
    Route::resource('pdfs', PDFController::class);
    Route::post('pdfs/generate-from-view', [PDFController::class, 'generateFromView'])->name('pdfs.generate');
    Route::put('pdfs/pdf/move', [PDFController::class, 'moveDisk'])->name('pdfs.move');
);

Route::get('share/pdf/token', [PDFController::class, 'share'])->name('pdf.share');


use Barryvdh\DomPDF\Facade\Pdf;

class InvoiceController extends Controller public function generateAndStore($orderId) $order = Order::with('items')->findOrFail($orderId); $pdf = Pdf::loadView('pdfs.invoice', ['order' => $order]);

    // Generate a unique filename
    $fileName = 'invoice_' . $order->invoice_number . '.pdf';
    $filePath = 'pdfs/' . $fileName;
// Store locally temporarily
    \Storage::disk('local')->put($filePath, $pdf->output());
// Now pass to your PDFDrive manager
    $pdfRecord = PDFDrive::store($filePath, $order);
return redirect()->route('pdf.show', $pdfRecord->id);


| Feature | Traditional Method | PDFDrive Pattern | |---------|--------------------|------------------| | Store PDF permanently | Manual Storage::put() | Built-in | | Queue support | Custom jobs needed | Works natively | | Temporary URLs | Hacky workarounds | Native filesystem feature | | Change storage backend | Rewrite logic | Change 1 config line |

Create a view that will be used to generate the PDF. In the example above, we are using a view named pdf.document.

php artisan make:view pdf/document

Then, edit the document.blade.php to include whatever content you want in your PDF:

<!-- resources/views/pdf/document.blade.php -->
<h1> $foo </h1>
<p>This is a sample PDF document.</p>

Any feature that generates dynamic content from user input must be secured. Laravel’s PDF drive inherits the framework’s robust security posture. Since PDFs are typically generated from Blade templates, automatic escaping of user-supplied data ( $user->name ) prevents XSS attacks that could otherwise be embedded into the output PDF. Additionally, Laravel’s authorization policies can gate who may generate or download specific PDFs, ensuring that sensitive documents like payroll slips or medical reports remain protected.

'driver' => 's3',

Pro tip: Set a default disk in your .env: To manage PDFs like a drive, you need a robust table

PDFDRIVE_DEFAULT_DISK=google_drive

Now your PDFDrive can seamlessly switch between local testing and production cloud storage.


Don't block HTTP requests. Dispatch a job:

php artisan make:job GenerateLargeReportPDF
class GenerateLargeReportPDF implements ShouldQueue
public function handle(PDFDriveService $pdfDrive)
$pdf = Pdf::loadView('reports.monthly-sales', $massiveDataset);
        $pdfDrive->storeFromContent($pdf->output(), 'Monthly_Report.pdf', $this->userId);
        // Notify user via email or notification
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.