Drag-and-drop PDF uploads with instant preview in javascript

TL;DR: This guide shows you how to build a simple drag-and-drop tool in JavaScript that lets users upload PDF files and instantly see a preview—just like modern file uploaders. It walks you through using plain HTML, JavaScript, and the browser’s built-in PDF preview tools, so there’s no need for heavy libraries. You’ll learn how to create a clean user experience with just a few lines of code, making it easy to add this feature to any web app. Perfect for developers who want a fast and simple way to let users upload and view PDFs.
PDF is the go-to format for handling user-accessible documents in web applications. From receipts for small online purchases to multi-million-dollar contracts, PDFs are everywhere!
Since the web runs on JavaScript, most apps handle basic PDF operations through JS tools spanning multiple libraries. But once you start implementing advanced features like drag-and-drop PDF uploads, instant previews, and editing, things can quickly get... less fun for developers and users.
To offer a seamless, modern drag-and-drop PDF upload and preview experience for users of your SaaS infrastructure, consider using Joyfill’s fillable PDF SDK and document API as shown in the following example.
Step 1: Create a JavaScript project
Open a terminal and run the following command to create a new JavaScript project using Vite.
cd pdf-upload
npm install
The above command will scaffold a vanilla JS project named pdf-upload. Navigate into the project folder and install its build tools by running the following commands.
Step 2: Generate a Joyfill Access Token
To implement drag-and-drop PDF upload and instant preview, we’ll need a Joyfill API access token. Complete the following steps to generate one:
Sign up for a Joyfill account if you don’t already have one.
In the Users dashboard of your Joyfill account, click the Access Tokens button to the right of your account information.
Click Add Access Token.
Copy the newly generated access token and set it as the value of the VITE_JOYFILL_ACCESS_TOKEN variable in the .env file at the root of the pdf-upload folder.
Step 3: Import Joyfill components from a CDN
Add the following <script> tag to the head element of the project’s index.html file. It will import Joyfill’s components into the application.
<script src='<https://cdn.jsdelivr.net/npm/@joyfill/components@latest/dist/joyfill.min.js>'></script>
Note that @joyfill/components can also be installed as an NPM package. However, for convenience, this example loads it through a CDN.
Step 4: Set Joyfill PDF form builder’s mount point
Add a div element to the body of the application’s index.html file and set “joyfill” as the value of the div’s id attribute.
<div id='joyfill'></div>
Step 5: Configure ‘Joyfill’ as an external library
Create a vite.config.js file at the root of the project’s folder and add the below configuration to it.
// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
build: {
rollupOptions: {
external: ['Joyfill'],
output: {
globals: {
Joyfill: 'Joyfill',
},
},
},
},
});
Step 6: Define helper functions to upload/preview PDF documents to/from Joyfill’s API
Create an src/upload-pdf.js file and add the following script to it.
// src/upload-pdf.js
async function onUploadAsync({ identifier }, [ fileUpload ]) {
if(fileUpload.type === 'application/pdf') {
// Convert the uploaded document’s File object to a dataURL
// compatible with Joyfill’s PDF to PNG converter API
const dataUri = await getDataUriForFileUpload(fileUpload);
// Convert the PDF’s pages to base64 encoded PNG images through
// Joyfill’s API
const base64DataUris = await convertPDFPagesToBase64(dataUri);
// Upload the base64 encoded PNG image URI to Joyfill’s documents API
const fileUploadPromises = base64DataUris.items.map((base64DataUri) => uploadFile(identifier, base64DataUri.url));
// Set the uploaded PNG pages as the background
// of each page to allow the placement/editing of text boxes etc. over them.
return Promise.all(fileUploadPromises);
}
}
async function getDataUriForFileUpload(fileUpload) {
return new Promise((res, rej) => {
const reader = new FileReader();
reader.readAsDataURL(fileUpload);
reader.onloadend = async () => {
res(reader.result);
};
});
};
const userAccessToken = import.meta.env.VITE_JOYFILL_ACCESS_TOKEN;
const apiBaseUrl = '<https://api-joy.joyfill.io>';
async function convertPDFPagesToBase64(dataUri) {
try {
const response = await fetch(`${apiBaseUrl}/v1/utilities/pdf/to/png/datauri`, {
method: 'POST',
mode: 'cors',
headers: {
'Authorization': `Bearer ${userAccessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ file: dataUri })
});
return await response.json();
} catch (error) {
console.log(error);
throw error;
}
};
async function uploadFile(docIdentifier, dataUri) {
const response = await fetch(`${apiBaseUrl}/v1/documents/${docIdentifier}/files/datauri`, {
method: 'POST',
mode: 'cors',
headers: {
'Authorization': `Bearer ${userAccessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ file: dataUri })
});
const data = await response.json();
return data;
};
export default onUploadAsync;
Step 7: Initialize Joyfill’s PDF form builder
Copy the following into the src/main.js file to initialize Joyfill.
// src/main.js
import onUploadAsync from './upload-pdf';
async function initJoyfill() {
Joyfill.JoyDoc(
document.getElementById('joyfill'),
{
mode: 'edit',
onUploadAsync
});
}
initJoyfill();
Step 8: Build and preview the application
Open a terminal and navigate to the pdf-upload folder. Then, run the following commands.
npm run build
npm run preview -- --host
Now, visit the URL displayed in the terminal (e.g., http://localhost:4173) to view the application in your browser.
Step 9: Drag and drop a PDF File to upload and preview it
Drag a PDF file into the file upload section around the top-right of the page and drop it to upload the document.
Fig. File upload section of Joyfill’s PDF form editor’s file upload button
Wait a few seconds (depending on your network speed) for the document preview to load.
That’s it! Now you can place elements from the form builder’s toolbar(s) over the document preview to edit it.
Need to build PDF form capabilities inside your SaaS application? Joyfill makes it easy for developers to natively build and embed form and PDF experiences inside their own SaaS applications.
Subscribe to my newsletter
Read articles from John Pagley directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by