A step-by-step guide on integrating PDF.js with Vue 3 and accessing the distribution folder locally

I must clarify that I am restricted from using any vue libraries to preview PDFs; only pure pdf.js and vue 3 are permitted.

  • Utilizing pdf.js for presenting PDF files within my vue 3 project.
  • Inquiring about the ideal folder structure for the project to ensure functionality.
  • Currently relying on a cdnjs link for pdf.js; looking to switch to the distribution folder instead.

View distribution folder here

Planning to replace the usage of cdnjs link with the distribution folder mentioned above.

  • Showcasing my current implementation along with examples provided on the official website of pdf.js.

pdf-view.vue

<template>
  <canvas :id="`the-canvas${index}`" style="border: 1px solid"></canvas>
</template>

<script setup>
import { onMounted, defineProps } from 'vue'

const { file, index } = defineProps(['file', 'index'])

onMounted(() => {
  import('https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/pdf.mjs').then((pdfjsLib) => {
    pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/pdf.worker.min.mjs'

    if (!file) return

    const fileReader = new FileReader()
    fileReader.onload = () => {
      const array = new Uint8Array(fileReader.result)
      const loadingTask = pdfjsLib.getDocument(array)
      loadingTask.promise.then(
        (pdf) => {
          const pageNumber = 1
          pdf.getPage(pageNumber).then((page) => {
            const scale = 1.5
            const viewport = page.getViewport({ scale })

            const canvas = document.getElementById(`the-canvas${index}`)
            const context = canvas.getContext('2d')
            canvas.height = viewport.height
            canvas.width = viewport.width

            // Render PDF page into canvas context
            const renderContext = {
              canvasContext: context,
              viewport: viewport
            }
            page.render(renderContext)
          })
        },
        (reason) => {
          // PDF loading error
          console.error(reason)
        }
      )
    }
    fileReader.readAsArrayBuffer(file)
  })
})
</script>

<style>

</style>

parent.vue

<template v-for="(file, index) in pdfFiles" :key="file">
            <pdfview :file="file.file" :index="index" />
</template>
<script setup>
import pdfview from '@/components/pdf-view/pdf-view.vue'
</script>

Current directory setup

--Project
  -public
  -src
  --components
  ---pdf-view
  ----pdf-view.vue [component]
  ---views
  ----parent.vue [component]

Answer №1

My Solution Steps

  • Download and install pdfjs-dist.

  • npm install pdfjs-dist

  • If you encounter the following error, follow these steps:

Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari14" + 2 overrides)

  • To address this issue, modify your vite.config.js file.
  • I discovered a solution from this post. Add the code snippet below to your vite.config.js file.
build: {
    target: "es2022"
  },
  esbuild: {
    target: "es2022"
  },
  optimizeDeps:{
    esbuildOptions: {
      target: "es2022",
    }
  }
  • Next, import the files like this:
import * as pdfjsLib from "pdfjs-dist";
import * as pdfWorker from "pdfjs-dist/build/pdf.worker.mjs";

If you omit the second import, you may encounter the error below.

pdfWorker is not defined

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieving and securely storing information using fetch() on authenticated REST services

Currently, I have successfully set up a React application that communicates with a REST backend which is built using Python and Flask. The specific functionality I have achieved involves downloading data from a database and saving it as a CSV file through ...

Is there a way to verify if a given input is a URL in VueJS?

Trying to determine if a user-input text is a URL in VueJS. Need assistance on crafting the regex for this task. Here's my current code! function checkIfValidUrl(url) { let regEx = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#= ...

Can one access non-static methods within React Navigation's navigationOptions?

Within my form, I am trying to position a submit button to the right of the header that triggers the same method as the submit button located at the bottom of the form. React Navigation necessitates the declaration of a static method named navigationOptio ...

Modify the background color of checkboxes without including any text labels

I am looking to customize my checkbox. The common method I usually see for customization is as follows: input[type=checkbox] { display: none; } .my_label { display: inline-block; cursor: pointer; font-size: 13px; margin-right: 15px; ...

When attempting to swap out ":customimage:" with an image in a React.js HTML view, the result displayed is [object Object]

I have created a function below: WordColonsToImage(comment) { var newcomment = comment.replace(/:wave:\s*/g, <img src={wavinghand} />) return newcomment } Here is an example: WordColonsToImage("Hi! :wave:") whi ...

Execute HTML and JS files through Eclipse PDT to view in a web browser

Is it possible to open HTML and JS files in a web browser within Eclipse PDT? Right now, only PHP files seem to launch successfully, otherwise an "Unable to Launch" dialog pops up. Any advice is appreciated! ...

Using Unicode JSON in Laravel blade to pass data to React components, encountering an issue with JSON parsing

I currently have a JSON object stored in the database: { "ui": {}, "title": "Hola mundo 2", "values": {}, "properties": {}, "description": "descripcion" } Within the Laravel controller, ...

Leveraging AngularJS to send a post request to the server through the $http

Can't seem to find a solution to my Angular issue, despite searching for it extensively? After starting to learn Angular recently, I've put together the following code based on various online resources. Here's the HTML: <div data-ng-ap ...

What are some strategies for preventing the $window.alert function from being triggered within an AngularJS controller's scope?

How can I prevent the alert from appearing on my dashboard? Do you have any suggestions? Thank you! I attempted to override the alert empty function in my controller, but I am still encountering the window alert when I navigate to my page. $window.alert ...

Using JSP to send variables from an external Javascript file

After creating a timer function, I am looking to display the results on a different page. The setup involves a JSP file calling functions from a separate JS file in order to output the information to another screen: Instructions in the JSP file: <butt ...

No results appearing in the output section

While developing a website using React, I encountered an error that said useState is defined but never used in the navbar component. To address this, I made changes to my ESLint configuration in the package.json file: "rules": { "eqeqe ...

Enhance JSON nesting with knockoutJS

I am currently working on updating a JSON object in memory using the knockout.js user interface. However, I have encountered an issue where changes made in the UI do not seem to reflect on the JSON data itself. To troubleshoot this problem, I have added bu ...

Encountering an issue with Meteor and node-celery: "Unable to access property 'slice' of null"

Check out the Github repository for reproducing this issue Run localhost:3000 to replicate the problem. In my setup with Meteor 1.4.4.1, I am utilizing the node-celery npm packages on the server side. Upon Meteor initialization, the client automatically i ...

Setting the title and meta tags in Nuxt.js using a middleware or plugin - a step-by-step guide

Is there a way to dynamically set NuxtJS title and meta tags using nuxt-middleware/nuxt-plugin? Currently, I am setting it in nuxt.config.js like this: head: () => { const now = Date.now() return { title: `config test : ${now}`, ...

I'm unable to resolve all parameters for xxx -- unit testing using jest

I recently encountered an issue with a test in jest that is failing and displaying the following error message: Error: Can't resolve all parameters for LoginService: (?). at syntaxError (/Users/wilson.gonzalez/Desktop/proyecto_andes/external/npm/nod ...

What is the best way to create a percentage glyphicon star icon that reflects a decimal average rating?

I have an average rating of 4.3 and I need to create a logic to display this as 4.3 stars (4 whole stars and the 5th star partially filled). The maximum rating is out of 5. Despite referring to examples on Stack Overflow and creating a JSFiddle, I am unabl ...

What is the method to retrieve the text within a textarea in Vue.js?

Looking to maintain the value of a variable in sync with a textarea's content. Avoiding the use of v-bind or v-model as the textarea is already bound to another value in a notebook app, like so: <textarea cols="30" rows="3" v-bind:value="note"> ...

Adding the vue-style-loader to your Vue.js project is a simple process that involves installing

In my project, I recently created a new file named header.vue within the src/components/header/ directory. The code for this file is as follows: <template> <div class="header"> I am header!! </div> </template> <script t ...

Assume we have two positive integers, N and X. In this scenario, N represents the total number of patients, while X denotes the time duration, measured in minutes, between the arrival

Suppose you are given two positive integers N and X. Here, N represents the total number of patients while X indicates the time duration (in minutes) after which a new patient will arrive. The doctor only provides 10 minutes to each patient for consultatio ...

Having trouble with data retrieval from MySQL using PHP and Angular on certain mobile devices, although it functions properly on desktops and laptops

The data retrieved from the mysql database is functioning properly on desktop and laptop, but not on mobile devices. The following HTML code is present in the html file: <table class="table table-default"> <thead> <tr> & ...