Browser API

PDFViewer

The <PDFViewer> component renders its slotted document inside an <iframe>, giving you a live preview that re-renders as the document changes. It runs usePDF internally.

Props

PropTypeDefaultDescription
styleStyle | Style[] | stringStyle applied to the iframe. Size the viewer here — there are no width/height props.
classNamestringClass applied to the iframe.
titlestringTitle attribute on the iframe, for accessibility.
showToolbarbooleantrueShows the browser PDF toolbar, via the #toolbar fragment on the blob URL.
documentDocumentTreeA prebuilt document tree ({ type, props, children }), for react-pdf API parity. Optional — prefer the default slot.
document takes a plain document tree object. To compose your PDF with the usual components, slot it in the default slot instead.

Slots

PropTypeDefaultDescription
defaultslotYour <Document> component. Rendered into a hidden container next to the iframe; its assembled tree drives the preview.
Note the difference from PDFDownloadLink and BlobProvider: those take the document in a #document slot because their default slot renders your own markup. PDFViewer renders only an iframe, so the document goes in the default slot.

Events

PropTypeDefaultDescription
render(payload: { url: string; blob: Blob }) => voidEmitted every time a new blob is produced, so you can wire up your own download button or upload the result.

Exposed Methods

PropTypeDefaultDescription
download(filename?)(filename?: string) => void'document.pdf'Downloads the currently rendered document.
getState()() => PDFStateReturns the latest render state: { url, blob, error, loading }.

Usage

Place a <Document> in the default slot and size the iframe with style:

vue
<script setup lang="ts">
import { PDFViewer } from '@vuepdf/renderer'
</script>

<template>
  <PDFViewer :style="{ width: '100%', height: '600px' }">
    <Document>
      <Page size="A4">
        <View :style="{ padding: 40 }">
          <Text :style="{ fontSize: 24 }">Hello, PDF!</Text>
        </View>
      </Page>
    </Document>
  </PDFViewer>
</template>
<PDFViewer> is a browser component, not a PDF primitive — it belongs in your page's markup, never inside a <Page>. Wrap it in <ClientOnly> in Nuxt, since it needs URL.createObjectURL.

Previewing a Component

Any component that renders a <Document> works, and updates as its props change:

vue
<script setup lang="ts">
import { PDFViewer } from '@vuepdf/renderer'
import InvoiceDocument from './InvoiceDocument.vue'

const invoice = ref({ id: '123', amount: 1500 })
</script>

<template>
  <PDFViewer :style="{ width: '100%', height: '600px' }" :show-toolbar="false">
    <InvoiceDocument :invoice="invoice" />
  </PDFViewer>
</template>

Downloads and Render Events

Listen for @render to react to each new blob, or call the exposed download() through a template ref:

vue
<script setup lang="ts">
import { PDFViewer } from '@vuepdf/renderer'

const viewer = useTemplateRef('viewer')

const onRender = ({ url, blob }: { url: string; blob: Blob }) => {
  console.log('rendered', url, blob.size)
}
</script>

<template>
  <PDFViewer ref="viewer" @render="onRender">
    <MyDocument />
  </PDFViewer>

  <button @click="viewer?.download('report.pdf')">Download</button>
</template>

See Also