A full-page print component powered by Paged.js for generating paginated, print-ready documents with headers, footers, and page numbers.
Renders a complete standalone HTML page formatted for printing. The title prop sets the page title and appears in the document footer.
A4 · Portrait · 20mm margin
<x-ui::document-print title="Annual Report">
<h1>Annual Report 2025</h1>
<p>This document is formatted for print using Paged.js.</p>
</x-ui::document-print>
Use the orientation prop to switch between portrait (default) and landscape. Landscape is ideal for wide tables and charts.
{{-- Portrait (default) --}}
<x-ui::document-print title="Portrait Doc" orientation="portrait">
<h1>Portrait Layout</h1>
<p>Standard vertical page layout.</p>
</x-ui::document-print>
{{-- Landscape --}}
<x-ui::document-print title="Landscape Doc" orientation="landscape">
<h1>Landscape Layout</h1>
<p>Wide horizontal page layout, great for tables and charts.</p>
</x-ui::document-print>
The pageSize prop accepts any valid CSS page size: A4 (default), Letter, Legal, and more.
A4
Letter
Legal
{{-- A4 (default) --}}
<x-ui::document-print title="A4 Document" pageSize="A4">
<h1>A4 Page</h1>
</x-ui::document-print>
{{-- US Letter --}}
<x-ui::document-print title="Letter Document" pageSize="Letter">
<h1>Letter Page</h1>
</x-ui::document-print>
{{-- US Legal --}}
<x-ui::document-print title="Legal Document" pageSize="Legal">
<h1>Legal Page</h1>
</x-ui::document-print>
The margin prop accepts any CSS shorthand value (default: 20mm). Use asymmetric values for binding margins or custom layouts.
10mm (tight)
25mm left (binding)
{{-- Tight margin --}}
<x-ui::document-print title="Tight Margins" margin="10mm">
<h1>Tight Margins</h1>
<p>10mm margin on all sides.</p>
</x-ui::document-print>
{{-- Asymmetric margin --}}
<x-ui::document-print title="Asymmetric Margins" margin="20mm 15mm 20mm 25mm">
<h1>Asymmetric Margins</h1>
<p>Top 20mm, Right 15mm, Bottom 20mm, Left 25mm (binding).</p>
</x-ui::document-print>
Set :autoPrint="true" to automatically open the browser's print dialog after Paged.js finishes rendering. Useful for invoice or label pages.
The print dialog opens automatically once Paged.js completes pagination — no button click needed. Route the user directly to this page.
<x-ui::document-print
title="Invoice #1042"
:autoPrint="true"
>
<h1>Invoice #1042</h1>
<p>The browser print dialog will open automatically after the page renders.</p>
</x-ui::document-print>
Inject additional CSS into the document <head> via the styles named slot. Override CSS variables or add component-specific print rules.
<x-ui::document-print title="Styled Report">
<x-slot name="styles">
:root {
--primary-color: #1e40af;
--text-color: #1f2937;
}
h1 { border-bottom: 3px solid var(--primary-color); padding-bottom: 0.5em; }
.highlight { background: #eff6ff; padding: 1em; border-left: 4px solid #1e40af; }
</x-slot>
<h1>Company Report</h1>
<div class="highlight">
<p>Custom styles are injected into the document head via the <code>styles</code> slot.</p>
</div>
</x-ui::document-print>
Because document-print outputs a complete <!DOCTYPE html> page, it cannot be embedded directly inside a Livewire component. The correct approach is a dedicated Blade route loaded inside an <iframe>. Alpine's $refs then lets you call contentWindow.print() to trigger printing scoped only to that iframe.
Invoice #1042
iframe loads the standalone Blade route — Paged.js renders inside it
1. Create a standalone Blade view
{{-- resources/views/documents/invoice.blade.php --}}
<x-ui::document-print title="Invoice #{{ $invoice->number }}">
<h1>Invoice #{{ $invoice->number }}</h1>
<p>Client: {{ $invoice->client->name }}</p>
</x-ui::document-print>
2. Register a plain route (no Livewire)
// routes/web.php
Route::get('/documents/invoice/{invoice}', fn (Invoice $invoice) =>
view('documents.invoice', compact('invoice'))
)->name('documents.invoice');
3. Embed in your Livewire component with a print button
<div x-data>
<div class="flex justify-end mb-4">
<x-ui::button x-on:click="$refs.preview.contentWindow.print()">
Print
</x-ui::button>
</div>
<iframe
x-ref="preview"
src="{{ route('documents.invoice', $invoice) }}"
class="w-full h-screen rounded-xl border border-gray-200 shadow"
></iframe>
</div>