Skip to content

Basic Usage

The VPV component, by default, will take the full size of its container which you can also set the width and height. The component is designed to be web responsive.

Import Vue PDF Viewer Component

To initiate VPV, you will first need to import VPdfViewer component.

Vue 3

There are two main ways to use VPV in your project, namely:

  • Composition API: A new method to organize and reuse logic by allowing developers to write components as functions.
  • Options API: A traditional method from Vue 2 where components are grouped into series of options.
vue
<script setup>
import { VPdfViewer } from "@vue-pdf-viewer/viewer";
</script>
<template>
  <div :style="{ width: '1028px', height: '700px' }">
    <VPdfViewer
      src="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf"
    />
  </div>
</template>
vue
<script>
import { VPdfViewer } from "@vue-pdf-viewer/viewer";

export default {
  components: { VPdfViewer },
  data() {
    return {
      src: "https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf",
    };
  },
};
</script>
<template>
  <div :style="{ width: '1028px', height: '700px'}">
    <VPdfViewer :src="src" />
  </div>
</template>

Nuxt

Because the VPV component is rendered on the client-side, you need to ensure it is loaded properly in a Nuxt project. Here are 3 recommended methods to integrate VPV:

  1. Register VPV with Nuxt auto-import components.

Register VPV in a local module to take advantage of Nuxt's auto-import feature. This allows you to use the component without importing it manually in every file. Refer to the Nuxt documentation on npm packages for details:

  • Create modules/register-components.ts, and use addComponent to register VPV globally:
    typescript
    import { addComponent, defineNuxtModule } from '@nuxt/kit'
    export default defineNuxtModule({
      setup() {
        addComponent({
          name: 'MyAutoImportedVPdfViewer',
          export: 'VPdfViewer',
          filePath: '@vue-pdf-viewer/viewer',
          mode: 'client'
        })
      },
    })
  • Use <MyAutoImportedVPdfViewer /> within <ClientOnly> tag in any file.
    vue
    <template>
      <!-- PDF works with client side only -->
      <ClientOnly>
        <div :style="{ width: '1028px', height: '700px'}">
          <MyAutoImportedVPdfViewer
            src="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf"
          />
        </div>
      </ClientOnly>
    </template>
  1. Create a Client Component

You can create your own client component with a .client suffix to ensure the component is only loaded on the client-side.

  • Create a client component

components/AppPdfViewer.client.vue

vue
<script lang="ts" setup>
  import { VPdfViewer, VPVBaseProps } from '@vue-pdf-viewer/viewer';
  const props = defineProps({ ...VPVBaseProps })
</script>
<template>
  <div :style="{ width: '1028px', height: '700px', margin: '0 auto' }">
    <VPdfViewer v-bind="$props" />
  </div>
</template>
  • Use the client component in your pages:

pages/index.vue

vue
<script setup lang="ts">
  const pdfSrc = ref('https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf')
</script>
<template>
  <h1>Index page</h1>
  <AppPdfViewer :src="pdfSrc" />
</template>

Remark: For more details, please refer to the Nuxt documentation on client components.

  1. Directly import and use it inside <ClientOnly> tag
vue
<script setup lang="ts">
  import { VPdfViewer } from "@vue-pdf-viewer/viewer";
</script>
<template>
  <!-- PDF works with client side only -->
  <ClientOnly>
    <div :style="{ width: '1028px', height: '700px'}">
      <VPdfViewer
        src="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf"
      />
    </div>
  </ClientOnly>
</template>

Remark: If you encounter the error 500 Promise.withResolve is not a function, it means that you are importing the VPdfViewer but not using it. Please ensure that any VPV components are only used within the client-side.

Nuxt Config

To avoid errors on the server-side when using the pdfjs-dist library in a Nuxt.js project, add the following snippet into your Nuxt config. This ensures that the library is transpiled only on the server side during the build process:

ts
// nuxt.config.ts
export default defineNuxtConfig({
  // ..
  build: {
    transpile: [
      (ctx) => ctx.isServer ? 'pdfjs-dist': false,
      (ctx) => ctx.isServer ? '@vue-pdf-viewer/viewer': false
    ]
  }
  // ..
})

Use VPV Globally

For better maintainability of your application’s components, it is advisable to create a reusable component. Vue components support fallthrough attributes, which is beneficial if your component uses VPV as its root. Additionally, VPV provides VPVBaseProps and default values, ensuring seamless integration.

src/components/AppPdfViewer.vue

vue
<script setup lang="ts">
  import { VPdfViewer, VPVBaseProps } from '@vue-pdf-viewer/viewer';

  const props = defineProps({
      ...VPVBaseProps, 
      title: {
        type: String,
        required: true
      }
    } as const
  )
</script>
<template>
  <div>
    <h2>
      {{ props.title }}
    </h2>
    <div :style="{ width: '1028px', height: '700px', margin: '0 auto'}">
      <VPdfViewer v-bind="props" />
    </div>
  </div>
</template>
vue
<script lang="ts">
  import { defineComponent } from 'vue'
  import { VPdfViewer, VPVBaseProps } from '@vue-pdf-viewer/viewer';
  export default defineComponent({
    components: { VPdfViewer },
    props: {
      ...VPVBaseProps,
      title: {
        type: String,
      },
    }
  })
</script>
<template>
  <div>
    <h2>
      {{ title }}
    </h2>
    <div :style="{ width: '1028px', height: '700px', margin: '0 auto' }">
      <VPdfViewer v-bind="$props" />
    </div>
  </div>
</template>
vue
<script setup>
  import { VPdfViewer, VPVBaseProps } from '@vue-pdf-viewer/viewer';

  const props = defineProps({
      ...VPVBaseProps, 
      title: {
        type: String,
        required: true
      }
    }
  )
</script>
<template>
  <div>
    <h2>
      {{ props.title }}
    </h2>
    <div :style="{ width: '1028px', height: '700px', margin: '0 auto'}">
      <VPdfViewer v-bind="props" />
    </div>
  </div>
</template>
vue
<script>
  import { defineComponent } from 'vue'
  import { VPdfViewer, VPVBaseProps } from '@vue-pdf-viewer/viewer';
  export default defineComponent({
    components: { VPdfViewer },
    props: {
      ...VPVBaseProps,
      title: {
        type: String,
      },
    }
  })
</script>
<template>
  <div>
    <h2>
      {{ title }}
    </h2>
    <div :style="{ width: '1028px', height: '700px', margin: '0 auto' }">
      <VPdfViewer v-bind="$props" />
    </div>
  </div>
</template>

Starter toolkits

Here are some links to starter toolkits to help you get started:

  1. Vue – Composition API - TypeScript
  2. Vue – Options API - TypeScript
  3. Vue – Composition API - JavaScript
  4. Vue – Options API - JavaScript
  5. Vue – SSR - TypeScript
  6. Nuxt
  7. VitePress
  8. Quasar

After executing the development command and opening the browser, here is how it will look.

Authenticate Your License

A valid key and an approved domain are required to remove the watermark on Vue PDF Viewer from such sites.

Add a license key

After making a license purchase, you should receive a license key. You could also access the License Manager to retrieve your license key. Here is how you can add the license key in your project.

Vue 3

vue
<script setup lang="ts">
  import { VPdfViewer, useLicense } from '@vue-pdf-viewer/viewer';
  
  // If the value is empty or incorrect, the watermark will remain.
  const licenseKey = import.meta.env.VITE_VPV_LICENSE ?? 'your-VPV-license-key';
  useLicense({ licenseKey });
  const pdfFileSource = "https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf";
</script>
<template>
  <div :style="{ width: '1028px', height: '700px'}">
    <VPdfViewer :src="pdfFileSource" />
  </div>
</template>

Nuxt

When using Nuxt, you have the option to store the license key on the server-side:

.env

sh
NUXT_VPV_LICENSE_KEY=your-VPV-license-key

nuxt.config.ts/js

js
export default defineNuxtConfig({
  // ... 
  runtimeConfig: {
    vpvLicenseKey: ''
  }
})

server/api/vpv-license-key.ts

js
export default defineEventHandler((event) => {
  const { vpvLicenseKey } = useRuntimeConfig(event)
  return {
    licenseKey: vpvLicenseKey
  }
})

components/AppPdfViewer.client.vue

vue
<script lang="ts" setup>
  import { VPdfViewer, useLicense, VPVBaseProps } from '@vue-pdf-viewer/viewer';

  const props = defineProps({ 
    ...VPVBaseProps, 
    title: String,
    licenseKey: { 
      type: String, 
      required: false 
    }
  })
  useLicense({ licenseKey: props.licenseKey });
</script>
<template>
  <div>
    <h2>
      {{ props.title }}
    </h2>
    <div :style="{ width: '1028px', height: '700px', margin: '0 auto' }">
      <VPdfViewer v-bind="$props" />
    </div>
  </div>
</template>

pages/index.vue

vue
<script setup lang="ts">
  // This will be requested on server-side
  const { data } = await useFetch<{ licenseKey: string }>('/api/vpv-license-key');
  // If the value is empty or incorrect, the watermark will remain.
  const licenseKey = computed(() => data.value?.licenseKey);
</script>
<template>
  <ClientOnly>
    <div :style="{ width: '1028px', height: '700px'}">
      <AppPdfViewer 
        src="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf"
        title="Shared Component"
        :licenseKey="licenseKey"
      />
    </div>
  </ClientOnly>
</template>

Add an approved domain

An approved domain restricts license key usage to only specific domains you approved. To start adding an approved domain, please access the License manager.

On the Approved Domain page, you can add as many domains as you like, including:

  • Localhost (e.g., localhost, localhost:3000) for local development
  • Domain names (e.g., example.com, www.example.com)
  • IP addresses (e.g., 192.168.1.1, 127.0.0.1:5173)

Important Notes

  • Domains are matched based on exact matches only. If you add example.com, only example.com will be approved. Subdomains like www.example.com or xyz.example.com will not work unless you add them separately.
  • Wildcard characters (*) are not supported at the moment. Each domain and subdomain need to be added individually.
  • Your license key will only function on these domains. Watermark in Vue PDF Viewer will still be visible on those domains that are not added.

An image of how to configure approved domain with Vue PDF Viewer

Remark: For more information on the licensing detail.