Skip to main content
The usePrint composable provides a flexible way to add printing functionality to your Vue 3 components with full TypeScript support.

Basic usage

Import and use the composable in your script setup:
<template>
  <div>
    <div id="content">
      <h1>Hello World!</h1>
      <p>This content will be printed.</p>
    </div>
    
    <button @click="handlePrint">Print</button>
  </div>
</template>

<script setup>
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

function handlePrint() {
  print('content', {
    windowTitle: 'My Document'
  })
}
</script>

Returned functions

The usePrint composable returns an object with several functions:

print

The main printing function:
print(element: HTMLElement | string, options?: PrintOptions): Promise<void>
<script setup>
import { ref } from 'vue'
import { usePrint } from 'vue-print-it'

const { print } = usePrint()
const contentRef = ref(null)

// Print by ID
function printById() {
  print('my-content')
}

// Print by element reference
function printByRef() {
  if (contentRef.value) {
    print(contentRef.value)
  }
}

// Print with options
function printWithOptions() {
  print('my-content', {
    windowTitle: 'Custom Title',
    preserveStyles: true,
    timeout: 1500
  })
}
</script>

printComponent

Print a Vue component reference:
<template>
  <div>
    <MyComponent ref="componentRef" />
    <button @click="printMyComponent">Print Component</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { usePrint } from 'vue-print-it'
import MyComponent from './MyComponent.vue'

const { printComponent } = usePrint()
const componentRef = ref(null)

function printMyComponent() {
  if (componentRef.value) {
    printComponent(componentRef.value)
  }
}
</script>

getBridgeStatus

Check if the bridge is available (requires bridge plugin):
<script setup>
import { ref, onMounted } from 'vue'
import { usePrint } from 'vue-print-it'

const { getBridgeStatus } = usePrint()
const bridgeStatus = ref(null)

onMounted(async () => {
  bridgeStatus.value = await getBridgeStatus()
  console.log('Bridge status:', bridgeStatus.value)
})
</script>

getAvailablePrinters

Get list of available printers (requires bridge plugin):
<script setup>
import { ref, onMounted } from 'vue'
import { usePrint } from 'vue-print-it'

const { getAvailablePrinters } = usePrint()
const printers = ref([])

onMounted(async () => {
  printers.value = await getAvailablePrinters()
})
</script>

<template>
  <div>
    <h3>Available Printers</h3>
    <ul>
      <li v-for="printer in printers" :key="printer.name">
        {{ printer.name }} 
        <span v-if="printer.is_default">(Default)</span>
      </li>
    </ul>
  </div>
</template>

printDirect

Print directly to a printer without dialog (requires bridge plugin):
<script setup>
import { usePrint } from 'vue-print-it'

const { printDirect } = usePrint()

async function printToSpecificPrinter() {
  const htmlContent = '<h1>Direct Print</h1><p>Sent directly to printer</p>'
  
  const result = await printDirect(htmlContent, {
    printer_name: 'HP LaserJet',
    content_type: 'html',
    copies: 2
  })
  
  console.log('Print job:', result)
}
</script>

TypeScript support

The composable has full TypeScript definitions:
import { usePrint, type PrintOptions } from 'vue-print-it'
import type { Ref } from 'vue'

const { print } = usePrint()

// Type-safe options
const options: PrintOptions = {
  windowTitle: 'Invoice',
  preserveStyles: true,
  timeout: 1000,
  onBeforePrint: () => console.log('Printing...'),
  onAfterPrint: () => console.log('Done!')
}

await print('invoice', options)

With reactive state

Manage printing state with Vue reactivity:
<template>
  <div>
    <div id="content">
      <h1>Document</h1>
      <p>Content to print</p>
    </div>
    
    <button 
      @click="handlePrint" 
      :disabled="isPrinting"
    >
      {{ isPrinting ? 'Printing...' : 'Print' }}
    </button>
    
    <p v-if="printError" class="error">
      {{ printError }}
    </p>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { usePrint } from 'vue-print-it'

const { print } = usePrint()
const isPrinting = ref(false)
const printError = ref('')

async function handlePrint() {
  isPrinting.value = true
  printError.value = ''
  
  try {
    await print('content', {
      onBeforePrint: () => {
        console.log('Starting print...')
      },
      onAfterPrint: () => {
        console.log('Print completed')
      },
      onPrintError: (error: Error) => {
        printError.value = error.message
      }
    })
  } finally {
    isPrinting.value = false
  }
}
</script>

Composable with computed content

Print dynamically computed content:
<script setup>
import { ref, computed } from 'vue'
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

const items = ref([
  { id: 1, name: 'Item A', price: 10 },
  { id: 2, name: 'Item B', price: 20 },
  { id: 3, name: 'Item C', price: 30 }
])

const selectedItems = ref([1, 3])

const itemsToPrint = computed(() => 
  items.value.filter(item => selectedItems.value.includes(item.id))
)

const total = computed(() => 
  itemsToPrint.value.reduce((sum, item) => sum + item.price, 0)
)

function printSelected() {
  print('selected-items', {
    windowTitle: `Selected Items - Total: $${total.value}`
  })
}
</script>

<template>
  <div>
    <div v-for="item in items" :key="item.id">
      <input 
        type="checkbox" 
        :value="item.id" 
        v-model="selectedItems"
      />
      {{ item.name }} - ${{ item.price }}
    </div>
    
    <div id="selected-items">
      <h2>Selected Items</h2>
      <div v-for="item in itemsToPrint" :key="item.id">
        {{ item.name }}: ${{ item.price }}
      </div>
      <p><strong>Total: ${{ total }}</strong></p>
    </div>
    
    <button @click="printSelected" :disabled="selectedItems.length === 0">
      Print Selected ({{ selectedItems.length }})
    </button>
  </div>
</template>

Reusable composable wrapper

Create your own custom composable:
// composables/useInvoicePrint.ts
import { usePrint, type PrintOptions } from 'vue-print-it'

export function useInvoicePrint() {
  const { print } = usePrint()
  
  const defaultOptions: PrintOptions = {
    windowTitle: 'Invoice',
    preserveStyles: true,
    timeout: 1500,
    styles: [
      '@page { margin: 1in; }',
      'body { font-family: Arial, sans-serif; }'
    ]
  }
  
  function printInvoice(invoiceId: string, options?: PrintOptions) {
    return print(invoiceId, {
      ...defaultOptions,
      ...options
    })
  }
  
  return {
    printInvoice
  }
}
Use your custom composable:
<script setup>
import { useInvoicePrint } from '@/composables/useInvoicePrint'

const { printInvoice } = useInvoicePrint()

function handlePrint() {
  printInvoice('invoice-123')
}
</script>

Next steps

Event callbacks

Handle before/after print events

Custom styles

Customize print layout with CSS

API Reference

View complete API documentation

TypeScript

TypeScript type definitions

Build docs developers (and LLMs) love