Koko
Koko

Reputation: 31

vueHtml2Pdf renders blank page (Nuxt)

I am using vueHtml2Pdf to generate my page to pdf, but when I wrap my content inside VueHtml2pdf tag nothing renders on my page, but it downloads when I click the download button. (Nuxt)

  methods: {
    downloadPDF() {
      this.$refs.html2Pdf.generatePdf()
    },
  },
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>



        <ArticleActions @download="downloadPDF()" />
    

    <client-only>
      <vue-html2pdf
        ref="html2Pdf"
        :show-layout="false"
        :enable-download="true"
        :pdf-quality="2"
        :manual-pagination="true"
        pdf-content-width="100%"
        :html-to-pdf-options="htmlToPdfOptions"
      >
        <section slot="pdf-content">
      <!-- content -->
          <div
            v-interpolation="{ newWindow: true }"
            class="articleContent__content"
            v-html="article.content"
          ></div>
      <!-- /content -->
        </section>
      </vue-html2pdf>
    </client-only>

Upvotes: 2

Views: 2387

Answers (2)

If someone looking for how to use html2pdf in nuxt 2.

  1. install html2pdf.js using npm or yarn
  2. create html-to-pdf.js file in nuxt plugin directory with below code
import html2pdf from 'html2pdf.js'

export default (context, inject) => {
  inject('html2pdf', html2pdf)
}
  1. Then add plugin to nuxt.config.js
 plugins: [
      '@/plugins/axios',
      ......
      { src: '@/plugins/html-to-pdf', mode: 'client' },
    ],
  1. How to use , example in your component menthod
  methods: {
    export() {
      this.$html2pdf(this.$refs.document, {
        margin: 1,
        filename: 'file-name.pdf',
        image: { type: 'jpeg', quality: 0.98 },
        html2canvas: {
          scale: 1,
          dpi: 192,
          letterRendering: true,
          ignoreElements: true,
        },
        jsPDF: { unit: 'pt', format: 'a2', orientation: 'portrait' },
      })
    },

Upvotes: 0

Aman Dalmia
Aman Dalmia

Reputation: 406

I have a working solution for Nuxtv3 (with server-side rendering). After trying a bunch of different vue-specific packages, including vue-html2pdf, I realized that most of them have been written for Vue2.

Instead, I chose to use html2pdf directly.

Upon directly importing html2pdf in the component where I need to add the functionality for converting html to pdf, Nuxt throws the following error: ReferenceError: self is not defined. This essentially happens because the line where the library is being imported runs on the server side as well and when it is imported, it tries to access a variable that isn't defined on the server side.

My solution was to create a custom plugin that runs only on the client side. It is very simple to do this in Nuxtv3 by just ending the filename with .client.ts as opposed to just .ts. Here is what plugins/html2pdf.client.ts looks like:

import html2pdf from 'html2pdf.js'

export default defineNuxtPlugin(() => {
  // had to make a plugin because directly importing html2pdf.js in the component
  // where I need to use it was causing an error as the import would run on the server
  // side and html2pdf.js is a client-side-only library. This plugin runs on the
  // client side only (due to the .client extension) so it works fine.
  return {
    provide: {
      html2pdf: (element, options) => {
        return html2pdf(element, options)
      }
    }
  }
})

Now, I can safely use it in my component as:

const { $html2pdf } = useNuxtApp()

function downloadPDF() {
  if (document) {
    const element = document.getElementById('html2pdf')

    // clone the element: https://stackoverflow.com/questions/60557116/html2pdf-wont-print-hidden-div-after-unhiding-it/60558415#60558415
    const clonedElement = element.cloneNode(true) as HTMLElement
    clonedElement.classList.remove('hidden')
    clonedElement.classList.add('block')
    // need to append to the document, otherwise the downloading doesn't start
    document.body.appendChild(clonedElement)

    // https://www.npmjs.com/package/html2pdf.js/v/0.9.0#options
    $html2pdf(clonedElement, {
      filename: 'filename.pdf',
      image: { type: 'png' },
      enableLinks: true
    })
    clonedElement.remove()
  }  
}

Basic usage of html2pdf: https://www.npmjs.com/package/html2pdf.js/v/0.9.0#usage

Configuration for html2pdf: https://www.npmjs.com/package/html2pdf.js/v/0.9.0#options

Upvotes: 5

Related Questions