Using onPrintError callback
TheonPrintError callback catches errors during printing:
<script setup>
import { ref } from 'vue'
import { usePrint } from 'vue-print-it'
const { print } = usePrint()
const errorMessage = ref('')
function handlePrint() {
print('content', {
onPrintError: (error: Error) => {
console.error('Print error:', error)
errorMessage.value = error.message
}
})
}
</script>
<template>
<div>
<button @click="handlePrint">Print</button>
<p v-if="errorMessage" class="error">{{ errorMessage }}</p>
</div>
</template>
Try-catch pattern
Wrap print calls in try-catch:<script setup>
import { ref } from 'vue'
import { usePrint } from 'vue-print-it'
const { print } = usePrint()
const errorMessage = ref('')
const isPrinting = ref(false)
async function handlePrint() {
isPrinting.value = true
errorMessage.value = ''
try {
await print('content', {
windowTitle: 'My Document'
})
} catch (error) {
console.error('Failed to print:', error)
errorMessage.value = 'Unable to print document. Please try again.'
} finally {
isPrinting.value = false
}
}
</script>
Common errors
Element not found
This error occurs when the element ID or reference doesn’t exist:<script setup>
import { usePrint } from 'vue-print-it'
const { print } = usePrint()
function handlePrint() {
const elementId = 'my-content'
// Check if element exists
const element = document.getElementById(elementId)
if (!element) {
console.error(`Element with ID "${elementId}" not found`)
return
}
print(elementId, {
onPrintError: (error) => {
if (error.message.includes('not found')) {
alert('The content to print is not available.')
}
}
})
}
</script>
Pop-up blocked
Browsers may block the print window:<script setup>
import { usePrint } from 'vue-print-it'
const { print } = usePrint()
function handlePrint() {
print('content', {
onPrintError: (error) => {
if (error.message.includes('blocked') || error.message.includes('popup')) {
alert('Please allow pop-ups for this site to enable printing.')
}
}
})
}
</script>
Timeout errors
If content takes too long to load:<script setup>
import { usePrint } from 'vue-print-it'
const { print } = usePrint()
function handlePrint() {
print('content', {
timeout: 3000, // Increase timeout for slow content
onPrintError: (error) => {
if (error.message.includes('timeout')) {
alert('Print preparation timed out. Please try again.')
}
}
})
}
</script>
Bridge connection errors
When using the bridge plugin:<script setup>
import { usePrint } from 'vue-print-it'
const { print, getBridgeStatus } = usePrint()
async function handlePrint() {
// Check bridge availability first
const status = await getBridgeStatus()
if (!status) {
alert('Print bridge is not available. Using browser print dialog instead.')
}
print('content', {
useBridge: !!status,
onPrintError: (error) => {
if (error.message.includes('bridge')) {
console.error('Bridge error, falling back to browser print')
// Retry without bridge
print('content', { useBridge: false })
}
}
})
}
</script>
User-friendly error messages
Provide helpful error messages to users:<template>
<div>
<div id="content">
<h1>Document</h1>
<p>Content to print</p>
</div>
<button @click="handlePrint" :disabled="isPrinting">
{{ isPrinting ? 'Printing...' : 'Print' }}
</button>
<div v-if="error" class="error-message">
<strong>Unable to print</strong>
<p>{{ error.userMessage }}</p>
<button @click="retryPrint">Try Again</button>
<button @click="error = null">Dismiss</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { usePrint } from 'vue-print-it'
const { print } = usePrint()
const isPrinting = ref(false)
const error = ref(null)
function getUserFriendlyMessage(error: Error): string {
if (error.message.includes('not found')) {
return 'The content you are trying to print is not available.'
}
if (error.message.includes('blocked') || error.message.includes('popup')) {
return 'Pop-ups are blocked. Please enable pop-ups for this site.'
}
if (error.message.includes('timeout')) {
return 'The print preview is taking too long. Please try again.'
}
if (error.message.includes('bridge')) {
return 'Unable to connect to the print service. Using browser print instead.'
}
return 'An unexpected error occurred. Please try again.'
}
async function handlePrint() {
isPrinting.value = true
error.value = null
try {
await print('content', {
onPrintError: (err) => {
error.value = {
original: err,
userMessage: getUserFriendlyMessage(err)
}
}
})
} catch (err) {
error.value = {
original: err,
userMessage: getUserFriendlyMessage(err)
}
} finally {
isPrinting.value = false
}
}
function retryPrint() {
error.value = null
handlePrint()
}
</script>
<style scoped>
.error-message {
margin-top: 20px;
padding: 15px;
background: #fee;
border: 1px solid #fcc;
border-radius: 4px;
}
.error-message button {
margin-right: 10px;
margin-top: 10px;
}
</style>
Logging and debugging
Log errors for debugging:<script setup>
import { usePrint } from 'vue-print-it'
const { print } = usePrint()
function logPrintError(error: Error, context: Record<string, any>) {
// Log to console
console.error('Print error:', {
message: error.message,
stack: error.stack,
...context
})
// Send to error tracking service
if (window.Sentry) {
window.Sentry.captureException(error, {
tags: {
action: 'print',
documentType: context.documentType
},
extra: context
})
}
// Log to analytics
if (window.analytics) {
window.analytics.track('Print Error', {
error: error.message,
...context
})
}
}
function handlePrint() {
const context = {
documentType: 'invoice',
documentId: 'INV-12345',
timestamp: new Date().toISOString(),
userAgent: navigator.userAgent
}
print('invoice', {
onPrintError: (error) => {
logPrintError(error, context)
}
})
}
</script>
Fallback strategies
Provide alternative methods if printing fails:<template>
<div>
<div id="content">
<h1>Document</h1>
<p>Content to print</p>
</div>
<div class="print-actions">
<button @click="handlePrint">Print</button>
<button @click="downloadPDF" v-if="showFallback">
Download PDF Instead
</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { usePrint } from 'vue-print-it'
const { print } = usePrint()
const showFallback = ref(false)
const errorCount = ref(0)
async function handlePrint() {
try {
await print('content', {
onPrintError: (error) => {
errorCount.value++
// Show fallback option after 2 failures
if (errorCount.value >= 2) {
showFallback.value = true
alert('Having trouble printing? Try downloading a PDF instead.')
}
}
})
} catch (error) {
console.error('Print failed:', error)
}
}
function downloadPDF() {
// Implement PDF download logic
window.location.href = '/api/documents/download-pdf'
}
</script>
Validation before printing
Validate content before attempting to print:<script setup>
import { ref } from 'vue'
import { usePrint } from 'vue-print-it'
const { print } = usePrint()
function validateContent(elementId: string): { valid: boolean; error?: string } {
// Check if element exists
const element = document.getElementById(elementId)
if (!element) {
return { valid: false, error: 'Element not found' }
}
// Check if element has content
if (!element.textContent?.trim()) {
return { valid: false, error: 'Element is empty' }
}
// Check if element is visible
if (element.offsetParent === null) {
return { valid: false, error: 'Element is hidden' }
}
return { valid: true }
}
function handlePrint() {
const validation = validateContent('content')
if (!validation.valid) {
alert(`Cannot print: ${validation.error}`)
return
}
print('content', {
onPrintError: (error) => {
console.error('Print error:', error)
}
})
}
</script>
Retry logic
Implement automatic retry with exponential backoff:<script setup>
import { usePrint } from 'vue-print-it'
const { print } = usePrint()
async function printWithRetry(
elementId: string,
maxRetries: number = 3,
baseDelay: number = 1000
) {
let lastError: Error | null = null
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
await print(elementId)
return // Success
} catch (error) {
lastError = error as Error
console.warn(`Print attempt ${attempt + 1} failed:`, error)
if (attempt < maxRetries - 1) {
// Wait before retrying (exponential backoff)
const delay = baseDelay * Math.pow(2, attempt)
await new Promise(resolve => setTimeout(resolve, delay))
}
}
}
// All retries failed
throw new Error(`Print failed after ${maxRetries} attempts: ${lastError?.message}`)
}
async function handlePrint() {
try {
await printWithRetry('content')
console.log('Print succeeded')
} catch (error) {
console.error('Print failed permanently:', error)
alert('Unable to print after multiple attempts. Please try again later.')
}
}
</script>
Debugging tips
Check browser console
Check browser console
Always check the browser console for error messages and stack traces.
Test in different browsers
Test in different browsers
Print behavior can vary between browsers. Test in Chrome, Firefox, Safari, and Edge.
Verify element visibility
Verify element visibility
Elements with
display: none or visibility: hidden may not print correctly:const element = document.getElementById('content')
console.log('Visible:', element.offsetParent !== null)
Check for CORS issues
Check for CORS issues
External stylesheets or images may fail to load due to CORS:
print('content', {
preserveStyles: false, // Try without styles
onPrintError: (error) => {
if (error.message.includes('CORS')) {
console.error('CORS issue detected')
}
}
})
Increase timeout for complex content
Increase timeout for complex content
Complex documents with many images may need more time:
print('content', {
timeout: 5000 // Increase from default 1000ms
})
Error recovery
Provide options to recover from errors:<template>
<div>
<div id="content">
<h1>Document</h1>
<p>Content to print</p>
</div>
<button @click="handlePrint">Print</button>
<div v-if="lastError" class="error-recovery">
<p class="error-message">{{ lastError.message }}</p>
<div class="recovery-options">
<button @click="retryWithoutStyles">
Retry without styles
</button>
<button @click="retrySimplified">
Retry simplified version
</button>
<button @click="openNewTab">
Open in new tab
</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { usePrint } from 'vue-print-it'
const { print } = usePrint()
const lastError = ref<Error | null>(null)
async function handlePrint() {
lastError.value = null
try {
await print('content', {
preserveStyles: true,
onPrintError: (error) => {
lastError.value = error
}
})
} catch (error) {
lastError.value = error as Error
}
}
function retryWithoutStyles() {
lastError.value = null
print('content', { preserveStyles: false })
}
function retrySimplified() {
lastError.value = null
// Create simplified version
const content = document.getElementById('content')
if (content) {
const simplified = document.createElement('div')
simplified.id = 'simplified-content'
simplified.textContent = content.textContent
document.body.appendChild(simplified)
print('simplified-content', {
onAfterPrint: () => {
simplified.remove()
}
})
}
}
function openNewTab() {
const content = document.getElementById('content')
if (content) {
const printWindow = window.open('', '_blank')
if (printWindow) {
printWindow.document.write(content.innerHTML)
printWindow.document.close()
printWindow.print()
}
}
}
</script>
Next steps
Event callbacks
Learn about print lifecycle events
Configuration
View all configuration options
Bridge printing
Alternative printing with bridge
API Reference
Complete API documentation