Working exemple with Nuxt
frederic117 opened this issue · 15 comments
Hello everybody
Is someone could providence a working tuto for an implémentation with Nuxt?
Thanks a lot
+1
+1
Hi!
Since I had a really bad time managing how to include vue-pdf in my Nuxt.js project, may be this could help someone.
This tuto shows how I managed to include vue-pdf in a vue, not as a plugin:
-
Create project
npx create-nuxt-app my-project
-
Install vue-pdf
npm install -s vue-pdf
-
Declare the package in nuxt.config.js
...
build: {
vendor: ['vue-pdf'],
extend(config, ctx) {
config.output.globalObject = 'this'
}
}
...
- Import the component in your .vue file (in the
<script>
tag)
<script>
var vuePdf;
if (process.browser) {
vuePdf = require('vue-pdf').default
}
export default {
...
components: {
vuePdf
}
...
}
</script>
- Use the component in your .vue (in the
<template>
tag)
<template>
<div>
<no-ssr>
<vuePdf src="https://your-pdf-file.com"></vuePdf>
</no-ssr>
</div>
</template>
- Run your app
npm run dev
- If you met this error
This dependency was not found:
* babel-runtime/regenerator in ./node_modules/pdfjs-dist/lib/web/ui_utils.js
To install it, you can run: npm install --save babel-runtime/regenerator
then run
npm install -s babel-runtime
Hope it will help!
Thank you very much @EmmanuelJego !
I still can't make this work
got window is not defined
And vendor is deprecated
:(
This should be a solution:
1- npm install -s vue-pdf
2- plugins/vue-pdf.js:
import Vue from 'vue'
import pdf from "vue-pdf";
Vue.component('pdf', pdf)
3- nuxt.config.js:
Add { src: '~/plugins/vue-pdf.js', ssr: false }
to plugins
Will be:
plugins: [
'~/plugins/axios',
{ src: '~/plugins/vue-pdf.js', ssr: false },
],
Add to extend(config, ctx)
Will be:
build: {
extend(config, ctx) {
config.output.globalObject = 'this'
config.module.rules.push(
{
test: /\.pdf$/,
loader: 'url-loader'
}
)
},
4- In .vue file
<template>
<div>
<client-only placeholder="Loading...">
<pdf
class="pdf"
:src="require('@/assets/example.pdf')"
:page="1"
></pdf>
</client-only>
</div>
</template>
<script>
export default {};
</script>
<style lang="css">
.pdf {
border: 1px solid red;
width: 100%;
height: 100%;
}
</style>
build: { extend(config, ctx) { config.output.globalObject = 'this' config.module.rules.push( { test: /\.pdf$/, loader: 'url-loader' } ) },
is only necessary when using require
inside src
. Since nuxtjs has a static folder it's enough to have files like /static/123.pdf
being loaded as <pdf src="/123.pdf" />
Here's how I solved this with Nuxt with no webpack extensions/modifications, etc. Works with multi-paged pdf's.
- Install via npm
npm install -save vue-pdf
- Create a plugin called vue-pdf.js:
import Vue from 'vue'
import pdf from "vue-pdf";
Vue.component('vue-pdf', pdf)
- Add to nuxt.config.js:
plugins: [
{ src: '~/plugins/vue-pdf.js', mode: 'client' },
]
- In your component, do the following.
<template>
<client-only>
<vue-pdf class="your-pdf-class" :src="pdfSrc" :page="1" @num-pages="pdfPageCount = $event"></vue-pdf>
<div v-if="pdfPageCount > 1">
<div v-for="(pageNum, index) in pdfPageCount " :key="index">
<vue-pdf class="your-pdf-class" :src="pdfSrc" :page="pageNum" v-if="pageNum > 1"></vue-pdf>
</div>
</div>
</client-only>
</template>
export default {
data() {
return {
pdfSrc: '/path-to-your-pdf',
pdfPageCount : 0,
}
}
}
And that's it. Make sure you wrap your template code in <client-only>
.
The import pdf from 'vue-pdf'
and the logic using it in the component script (such as pdf.createLoadingTask
from the examples) were causing it to break for me, so I just shifted the majority of the logic to the template.
For further modification, using the props and events in the API should be enough to get the job done.
Access to fetch at 'http://127.0.0.1:1001/status/204+IDM' (redirected from 'https://cdn.filestackcontent.com/wcrjf9qPTCKXV3hMXDwK') from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
this is alert returns to the console
@jerrychico this is an issue with the source of your PDF - it seems like cdn.filestackcontent.com does not allow you to access their files directly in a browser. You could try to proxy the request with nuxt-proxy and see if you can bypass this issue. It does not have anything todo with vue-pdf
@danielrjames First of all, thanks for your suggestion. It worked for me.
However, if the PDF has 'n' pages, it will make 'n' API calls to the file - one for each page.
If you open the console and you'll notice it on the network activity.
I tried to import the pdf library to use the createLoadingTask() method however I get the 'missing stake frame' error.
Is that what happened to you as well?
@tpanthier Yes, that's what was happening for me.
I didn't realize the api was calling for each page. It's a small price to pay for a working solution, but I can see how that can be a pain if you're dealing with pdfs that are very long.
@tpanthier @danielrjames
You can do this to resolve it:
Plugins pdf:
import Vue from 'vue'
import pdf from 'vue-pdf'
export default function () {
Vue.component('pdf', pdf)
Vue.prototype.pdf = pdf
}
And in your component:
this.pdfSrc = Vue.prototype.pdf.createLoadingTask(this.url)
Here is the simplest solution :
components: {
pdf: () => import('vue-pdf')
},
This should be a solution:
1-
npm install -s vue-pdf
2- plugins/vue-pdf.js:
import Vue from 'vue' import pdf from "vue-pdf"; Vue.component('pdf', pdf)
3- nuxt.config.js: Add
{ src: '~/plugins/vue-pdf.js', ssr: false }
to plugins Will be:plugins: [ '~/plugins/axios', { src: '~/plugins/vue-pdf.js', ssr: false }, ],
Add to
extend(config, ctx)
Will be:build: { extend(config, ctx) { config.output.globalObject = 'this' config.module.rules.push( { test: /\.pdf$/, loader: 'url-loader' } ) },
4- In .vue file
<template> <div> <client-only placeholder="Loading..."> <pdf class="pdf" :src="require('@/assets/example.pdf')" :page="1" ></pdf> </client-only> </div> </template> <script> export default {}; </script> <style lang="css"> .pdf { border: 1px solid red; width: 100%; height: 100%; } </style>
At first thanks for showing the tuto!!
Although I followed this tuto, I got an error as following.
vuePdfNoSss.vue:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<style src="./annotationLayer.css"></style>
SyntaxError: Unexpected token '<'
Vue.component('vue-pdf', pdf)
Does anyone knows how to solve this error?? :(
ref: #13