Quick Summary
Discover how Browsershot Laravel makes PDF generation effortless and precise. From setting up headless Chrome to creating Blade views, handling orders, and automating storage, this guide covers it all. Learn essential security practices, optimize performance with queues and caching, and generate professional PDFs reliably. It is perfect for invoices, reports, or any downloadable content. Efficient, safe, and fully integrated with Laravel.
Table of Contents
Creating PDFs from web pages or HTML in Laravel can feel tricky. But with Browsershot, it becomes a seamless task.
This tool taps into the power of headless Chrome, letting you generate clean, professional PDFs in just a few lines of code and it works perfectly alongside Laravel Cloudinary when you want to manage and render high-quality images within your generated PDFs.
So, if you’re building invoices, reports, or downloadable content for users, Browsershot simplifies the process while giving you full control over layout and style. In this blog, we’ll explore how to use Browsershot in Laravel to create PDFs effortlessly, saving you time and avoiding the usual headaches of document generation.
What is Browsershot?
Browsershot Laravel is a powerful package that makes generating PDFs and capturing screenshots from web pages effortless. It uses headless Chrome along with Puppeteer to render pages exactly like a real browser. This ensures that all HTML, CSS, and JavaScript elements appear correctly in your final output — similar to how Laravel Scout efficiently indexes and retrieves data for seamless search experiences.
Using Browsershot, you can convert web pages or raw HTML into a PDF in Laravel quickly and reliably. Here are the key benefits:
- Quickly turn web pages or HTML content into PDFs, ideal for reports, invoices, and downloadable documents.
- Renders pages with headless Chrome, so CSS and JavaScript display accurately.
- Integrates seamlessly with Laravel, requiring minimal setup to generate PDFs and screenshots.
- Provides control over page sizes, margins, and custom headers and footers for professional output.
- Perfect for automated document generation in applications like reporting systems or eCommerce platforms.
How to Use Browsershot Laravel for PDF Generation?
Now that we understand what Browsershot is and the benefits it brings, let’s dive into the steps to set it up and start generating PDFs in Laravel. Follow this straightforward process to integrate Browsershot into your application and quickly begin creating PDFs directly from your web content.
Prerequisites
- Laravel Project: Have a Laravel project ready. Or create a new Laravel project.
- PHP 8.1+: Ensure your PHP version is 8.1 or higher.
- Composer: Needed to install Browsershot.
- Node.js and npm: Verify they’re installed by running node -v and npm -v.
- Basic Laravel Skills: Familiarity with models, controllers, and views.
- Chrome or Chromium: Browsershot uses headless Chrome; Puppeteer will handle this.
Step 1: Set Up Browsershot in Laravel
First, ensure you have Browsershot installed:
composer require spatie/browsershot
Next, install Node.js and Puppeteer (if you haven’t already):
npm install puppeteer
Finally, verify your installation to ensure everything is set up correctly:
node -v # Check Node.js version
npm -v # Check npm version
Once these steps are complete, Browsershot is ready to use in your Laravel project.
Step 2: Create the Model
In this example, we’ll create a simple Order model with dummy data.
- Generate the Order Model and Migration:
php artisan make:model Order -m
Open the migration file in database/migrations and define the columns for our orders table:
public function up()
{
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->string('product_name');
$table->integer('quantity');
$table->decimal('price', 8, 2);
$table->unsignedBigInteger('user_id');
$table->timestamps();
});
}
- Run the Migration:
php artisan migrate
- Define Relationships (Optional):
If you have a User model, you can add a relationship between Order and User:
// In Order.php
public function user()
{
return $this->belongsTo(User::class);
}
Step 3: Create the Controller
Next, create a controller to handle the PDF generation logic.
Generate the OrderController:
php artisan make:controller OrderController
Then, implement the generatePDF() method in the newly created controller:
use Spatie\Browsershot\Browsershot;
use App\Models\Order;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\File;
use Illuminate\Http\Response;
class OrderController extends Controller
{
public function generatePDF($orderId)
{
// Retrieve the order by ID
$order = Order::with('user')->findOrFail($orderId);
// Pass data to the view
$htmlContent = View::make('orders.invoice', compact('order'))->render();
// Ensure the invoices directory exists
$invoicePath = public_path('invoices');
if (!File::exists($invoicePath)) {
File::makeDirectory($invoicePath, 0755, true);
}
// Define PDF file path
$pdfPath = $invoicePath . "/order-{$orderId}.pdf";
try {
// Generate PDF with Browsershot
Browsershot::html($htmlContent)
->format('A4')
->margins(10, 10, 10, 10)
->save($pdfPath);
return response()->download($pdfPath);
} catch (\Exception $e) {
// Handle Puppeteer or Browsershot errors
return response()->json([
'message' => 'Failed to generate PDF. Please try again.',
'error' => $e->getMessage()
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
}
Step 4: Create the Blade View
Now, let’s create a Blade view for the invoice. This HTML will be rendered by Browsershot and converted into a PDF.
- Create the View File
In resources/views/orders, create a new file called invoice.blade.php.
- Example Invoice HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Order Invoice</title>
<style>
body { font-family: Arial, sans-serif; margin: 0; padding: 0; }
.invoice-box { max-width: 800px; margin: auto; padding: 30px; border: 1px solid #eee; background: #f9f9f9; }
.invoice-header { font-size: 24px; font-weight: bold; margin-bottom: 20px; text-align: center; }
.invoice-footer { font-size: 12px; text-align: center; margin-top: 30px; color: #888; }
.invoice-table { width: 100%; border-collapse: collapse; margin-top: 20px; }
.invoice-table th, .invoice-table td { border: 1px solid #ddd; padding: 8px; text-align: left; }
.total { font-weight: bold; }
</style>
</head>
<body>
<div class="invoice-box">
<!-- Header -->
<div class="invoice-header">Order Invoice</div>
<!-- Customer Details -->
<p><strong>Customer:</strong> {{ $order->user->name }}</p>
<p><strong>Date:</strong> {{ $order->created_at->format('Y-m-d') }}</p>
<!-- Invoice Table -->
<table class="invoice-table">
<thead>
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ $order->product_name }}</td>
<td>{{ $order->quantity }}</td>
<td>${{ $order->price }}</td>
<td>${{ $order->quantity * $order->price }}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3" class="total">Total:</td>
<td class="total">${{ $order->quantity * $order->price }}</td>
</tr>
</tfoot>
</table>
<!-- Footer -->
<div class="invoice-footer">
Thank you for your business!
</div>
</div>
</body>
</html>
Notes on Enhancements
- Custom Styles: You can adjust fonts, colors, borders, and padding to match your branding.
- Headers and Footers: Browsershot can repeat header/footer content on every page using HTML sections like .invoice-header and .invoice-footer.
- CSS Background Support: When generating the PDF, use .showBackground() in Browsershot to ensure your CSS backgrounds are rendered:
Browsershot::html($htmlContent)
->format('A4')
->margins(10, 10, 10, 10)
->showBackground() // Renders CSS backgrounds in PDF
->save($pdfPath);
This setup ensures your PDFs look polished, professional, and faithful to your web design.
Step 5: Define a Route for PDF Generation
Add a route in routes/web.php that maps to the generatePDF method:
use App\Http\Controllers\OrderController;
Route::get('/order/{id}/pdf', [OrderController::class, 'generatePDF'])->name('order.pdf');
Step 6: Test PDF Generation
- Access the Route
To test PDF generation, visit the route in your browser with a valid order ID:
http://localhost:8000/order/1/pdf
If everything is set up correctly, a PDF named order-1.pdf should be generated and downloaded automatically.
- Seed the Database (Optional)
If you don’t have test data, consider seeding the orders table to ensure there’s an order to generate a PDF from.
Troubleshooting Common Puppeteer Issues
While testing, you may encounter Puppeteer-related errors. Here’s how to resolve the most common ones:
- Chromium Missing: Puppeteer requires Chromium to run. Make sure Node.js and Puppeteer are installed, and try reinstalling Puppeteer:
npm install puppeteer
- Timeout Errors: If the PDF takes too long to generate, increase the timeout:
Browsershot::html($htmlContent)->timeout(120)->save($pdfPath);
- Permissions Issues: Ensure your Laravel project has write permissions for /public/invoices/. Use:
chmod -R 755 public/invoices
By following these steps, you can confirm that PDF generation works reliably in your Laravel application.
Step 7: Automate PDF Creation (Optional)
You can modify the generatePDF method to store PDFs in the storage/ directory instead of downloading them. This is useful for record-keeping or generating PDFs in bulk.
Example: Save PDF with Storage
use Illuminate\Support\Facades\Storage;
public function generatePDF($orderId)
{
$order = Order::with('user')->findOrFail($orderId);
// Render HTML from the Blade view
$htmlContent = View::make('orders.invoice', compact('order'))->render();
// Generate PDF content with Browsershot
$pdfContent = Browsershot::html($htmlContent)
->format('A4')
->margins(10, 10, 10, 10)
->showBackground()
->pdf();
// Store the PDF in storage/app/invoices/
Storage::put("invoices/order-{$orderId}.pdf", $pdfContent);
return response()->json(['message' => 'PDF generated and stored successfully.']);
}
This will save the PDF at:
storage/app/invoices/order-{orderId}.pdf
Bulk PDF Generation
For large volumes of orders, you can queue the PDF generation to run in the background instead of processing synchronously. Similarly, you could use Laravel with MongoDB to store structured data efficiently when working with large document or report systems.
For example:
GenerateInvoicePdf::dispatch($orderId);
- Create a queued job GenerateInvoicePdf that runs the same Browsershot logic.
- This approach avoids timeouts and keeps your application responsive.
Using storage and queues ensures PDFs are managed efficiently, especially in applications handling multiple orders or automated reports.
Security Best Practices
When generating PDFs from HTML in Laravel, it’s essential to follow security precautions. Here’s a clear guide:
- Sanitize User Input: Always clean HTML provided by users before rendering it. Use a trusted library or built-in Laravel functions to remove unsafe tags and attributes. This ensures the HTML used in PDFs is safe and free from malicious code.
- Prevent Script Injection: Never include raw JavaScript or dynamic scripts from users. Browsershot executes HTML like a real browser. Unsafe scripts could run and compromise your server or data. Strip or escape any potentially harmful content before rendering.
- Use Safe HTML Practices: Stick to static HTML and CSS for PDFs. Avoid external scripts, inline event handlers, or untrusted content. Regularly review templates to ensure they don’t introduce vulnerabilities.
Simply put, always sanitize user-provided HTML and stick to static content when generating PDFs in Laravel. This prevents script injection and ensures your PDF output is safe and secure.
Conclusion
With Browsershot, generating PDFs in Laravel becomes quick and hassle-free. By following these steps, you can create polished, downloadable documents like invoices and reports straight from your app.
Whether for personal projects or professional needs, Browsershot makes PDF creation easy and reliable. Give it a try and see how it enhances your Laravel application!
For advanced customizations and seamless integration, collaborate with a Laravel development company or hire Laravel developers to ensure scalability, security, and long-term performance.
FAQs Related to Browsershot Laravel Automation and Integrations
How can I use Laravel to automate document creation and reminders?
You can set up CRM integration for reminder system to automate sending reminders and alerts directly from your Laravel application, improving efficiency and reducing manual work.
Can Laravel help in building automated PDF or notification workflows?
Absolutely! Laravel’s job queues and schedulers allow seamless automation and you can also know how to develop an Automated Reminder System to trigger actions based on user or order activity.
Need Easy PDF Generation in Laravel?
Want professional-looking PDFs without the hassle? Our team can help you integrate Browsershot Laravel to automate and streamline your PDF generation process effortlessly.


