Skip to content

Nuxt.js Image to Pdf Converter

We may need to switch formats whenever we need to deliver image content to our users, depending on business requirements and the user’s device configurations. This is especially true for image/PDF formats. In this article, we review how we can easily achieve this using Cloudinary and Nuxt.Js.

The complete project can be found on the CodeSandbox, you can fork it and add the following environment variables to your sandbox server to make it work.

NUXT_ENV_CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=

The complete codebase can also be found on Github

We will be using beginner-level Nuxt.Js and Express.Js in this tutorial. Thus we recommend previous knowledge and experience in JavaScript and Vue.Js.

Node.Js, Express.Js, and Nuxt.Js knowledge and experience are not a requirement.

Ensure Node.Js is installed on your system. Npx also needs to be installed as well. It is shipped by default since npm 5.2.0, npm v6.1, or yarn.

Run the following command to create the project


yarn create nuxt-app nuxtjs-image-pdf-converter

We recommend installing axios during the prompt as we will use it to interact with the Express.Js server.

Since we will have both client and server-side operations, we recommend selecting the Universal (SSR/SSG) rendering mode and Server (Node.Js hosting) deployment mode.

Here is a compilation of our recommended setup:

  • Project Name: nuxtjs-image-pdf-converter

  • Programming Language -> JavaScript

  • Package manager -> Yarn

  • UI Framework -> TailwindCSS

  • Nuxt.Js modules -> Axios

  • Linting tools -> None

  • Rendering mode -> Universal (SSR/SSG)

  • Deployment target -> Server (Node.Js hosting)

  • Development tools -> None

  • Continuous integration -> None

  • Version control -> Git

Once the above setup is complete, Enter the project folder with the following command:


cd nuxtjs-image-pdf-converter

Cloudinary doesn’t come installed by default in Nuxt.Js, thus we need to install the recommended package using the following command


yarn add @nuxtjs/cloudinary

# OR

npm install @nuxtjs/cloudinary

Code language: CSS (css)

Once the dependency has been added to our project, let’s add @nuxt/cloudinary as a module in our nuxt.config.js modules section. This registers the package in our Nuxt.Js project.


// nuxt.config.js

export  default  {

modules:  [

'@nuxtjs/cloudinary'

]

}

Code language: JavaScript (javascript)

To configure our Cloudinary instance, we’ll add a cloudinary section to our nuxt.config.js


// nuxt.config.js

cloudinary:  {

cloudName:  process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME,

secure:  true

}

Code language: JavaScript (javascript)

We do not want our cloud name exposed in our project code. For this reason, we’ll create a .env file. By default, this file is ignored by git and will not be committed to our remote code repository.


// .env

NUXT_ENV_CLOUDINARY_CLOUD_NAME=my-cloudinary-cloud-name

Code language: JavaScript (javascript)

Nuxt.Js allows us to add our own custom middleware. We are going to use this to create an Express.Js API without creating our own dedicated external server.

We are first going to install Express.Js


yarn add express

# OR

npm install express

Code language: PHP (php)

We will create a file server-middleware/api.js to handle our API requests:


// server-middleware/api.js

const  app  =  require('express')()

app.all('/generate-pdf',  async  (req,  res)  =>  {

res.json({ data:'data'  })

})

module.exports  =  app

Code language: JavaScript (javascript)

The above code enables our API to handle all api/generate-pdf requests.

To register our API with Nuxt.Js we will need to register it in the serverMiddleware section of nuxt.config.js


// nuxt.config.js

serverMiddleware:  [

{ path:  "/api", handler:  "~/server-middleware/api.js"  },

],

Code language: JavaScript (javascript)

This will ensure that all /api requests are routed to our API.

To interact with Cloudinary from our Express.Js server, we’ll need to install the Node.Js SDK as well. We’ll use the following command to install it:


yarn add cloudinary

# OR

npm install cloudinary

Code language: PHP (php)

Once installed, we’ll need to load and configure the SDK in our api.js


// server-middleware/api.js

require('dotenv').config()

const  cloudinary  =  require('cloudinary');

cloudinary.config({

cloud_name:  process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME,

api_key:  process.env.CLOUDINARY_API_KEY,

api_secret:  process.env.CLOUDINARY_API_SECRET,

secure:  true

});

...

Code language: JavaScript (javascript)

We do not want our API Key and Secret exposed to our code repository. We will thus add them to our .env file


// .env

...

CLOUDINARY_API_KEY=secret-api-key

CLOUDINARY_API_SECRET=secret-api-secret

Code language: JavaScript (javascript)

Let us render a simple form allowing our users to upload images.


<!-- pages/images-to-pdf.vue -->

<form @submit.prevent="submit">

<input

multiple

accept=".jpeg,.jpg,.png,image/jpeg,image/png"

type="file"

name="images"

/>

<button type="submit">

Convert

</button>

</form>

Code language: HTML, XML (xml)

To convert images to PDF, we’ll first upload them to cloudinary. During the upload process, we’ll assign them a unique tag. We will then use this tag to generate the PDF.

We’ll use a Promise.all to ensure all the images are uploaded. Once the images are uploaded, we then call the api/generate-pdf endpoint with the new tag as a query parameter. This request should return an instance object containing the secure_url to our PDF document.


// pages/images-to-pdf.vue

export  default  {

data()  {

return  {

pdfUrl:  null

};

},

methods:  {

async  submit(e)  {

const  randomTag  =  Math.random().toString(36).substring(7);

this.uploading  =  true;

const  files  =  e.target.images.files;

const  uploadedFiles  =  await  Promise.all(

Array.from(files).map(async  (file)  =>  {

/* create a reader */

const  readData  =  (f)  =>

new  Promise((resolve)  =>  {

const  reader  =  new  FileReader();

reader.onloadend  =  ()  =>  resolve(reader.result);

reader.readAsDataURL(f);

});

  
/* Read data */

const  data  =  await  readData(file);

  
/* upload the converted data */

return  await  this.$cloudinary.upload(data,  {

upload_preset:  "nuxtjs-image-pdf-converter",

folder:  `nuxtjs-image-pdf-converter/images/${randomTag}`,

tags:  [randomTag],

});

})

);

const  resp  =  await  this.$axios.get(`/api/generate-pdf?tag=${randomTag}`);

  

this.pdfUrl  =  resp.data.pdf.secure_url;

  

this.uploading  =  false;

},

},

};

Code language: JavaScript (javascript)

Within our api.js, we will call on the cloudinary multi method. This is the method we will use to create a single PDF from all the uploaded images.

To do this, we will update the configuration we created for the route /generate.pdf. This is the code contained in the app.all(..) method we created earlier.


//server-middleware/api.js

app.all('/generate-pdf',  async  (req,  res)  =>  {

const  pdf  =  await  cloudinary.v2.uploader.multi(

req.query.tag,

{ format:  "pdf"  },

);

  

res.json({ pdf:  pdf  })

})

Code language: JavaScript (javascript)

We will call the method requesting cloudinary to create a new pdf. We will then send back the response to our front-end.

We will then render a link on the front-end allowing our users to view the newly created PDF.


<!-- pages/images-to-pdf.vue -->

<a

:href="pdfUrl"

target="_blank"

>

View PDF

</a>

Code language: HTML, XML (xml)

We will first ensure that only PDF file types can be uploaded by our users. This can be done using simple HTML


<!-- pages/pdf-to-images.vue -->

<form @submit.prevent="submit">

<input

type="file"

accept="application/pdf"

name="pdf"

/>

<button>Convert</button>

</form>

Code language: HTML, XML (xml)

On upload, we will upload the PDF document to cloudinary. We will receive an object containing the public_id and the pages in the document on upload. We will then use this data to generate URLs rendering each page as an image.

To achieve this, let us add the following code to the section of our pages/pdf-to-images.vue file. You can find the whole file on github here.


// pages/pdf-to-images.vue

export  default  {

data()  {

return  {

images:  null,

};

},

methods:  {

async  submit(e)  {

this.uploading  =  true;

const  file  =  e.target.pdf.files[0];

/* create a reader */

const  readData  =  (f)  =>

new  Promise((resolve)  =>  {

const  reader  =  new  FileReader();

reader.onloadend  =  ()  =>  resolve(reader.result);

reader.readAsDataURL(f);

});

/* Read data */

const  data  =  await  readData(file);

/* upload the converted data */

const  upload  =  await  this.$cloudinary.upload(data,  {

upload_preset:  "nuxtjs-image-pdf-converter",

folder:  `nuxtjs-image-pdf-converter/PDFs`,

});

this.images  =  [];

for  (let  page  =  1;  page  <=  upload.pages;  page++)  {

this.images.push({

page,

url:  this.$cloudinary.image.url(upload.public_id,  {

page,

}),

});

}

this.uploading  =  false;

},

},

};

Code language: JavaScript (javascript)

Once the images array has been filled with the links, we can then render them for our users to view:


<!-- pages/pdf-to-images.vue -->

<ul>

<li v-for="(image, index) in images"  :key="index">

<a

:href="image.url"

target="_blank"

>

Page {{ image.page }}

</a>

</li>

</ul>

Code language: HTML, XML (xml)

To run the project locally, use the following command in the nuxtjs-image-pdf-converter project folder:


yarn dev

# OR

npm run dev

Code language: PHP (php)

In the above article, we have reviewed how to convert PDFs to images and vice versa with the help of Cloudinary. There are additional formats we can convert between with additional options. Feel free to review the resources to read on what’s possible.

Cloudinary Nuxt

Express.Js

Vue.Js

Back to top

Featured Post