Export a PDF they say...it'll be simple they say...
"Our users want to share their reports, can you just add an export button? Ideally by tomorrow" - Project Managers
Many SaaS companies have user dashboards and metrics. It's where users actually understand how the tool or service helps them.
But, what about if they want to share those numbers around?
You don't want them to hit Print to PDF or just send a screengrab since that gives unprofessional results. So, you might look at a method like jsPDF. It typically runs on the client side, meaning it clogs up the visitor's device and gives inconsistent results.
Automating the process through Puppeteer is much more reliable. It gives you advanced abilities such as inserting style tags and handling log ins.
We'll share with you a puppeteer pdf generator code snippet that can run in your own Puppeteer instance, or with our hosted browsers.
How to automate PDF generation with puppeteer-core
Let's demonstrate an export with our own account dashboard. The script will:
- Define our variables and endpoint
- Set the viewport
- Wait for network traffic for idle
- Submit login credentials
- Remove unwanted elements
- Prevent CSS shifts and font swaps
- Print the page with a background
You can run this script with the default puppeteer
library, but we would always recommend using puppeteer-core
. Puppeteer includes a bundled Chrome instance, which is suitable for running locally but is bad for scaling on cloud hosting. Puppeteer-core only contains the library so that you can run the browsers on a separate server (or use ours), similar to how you'd host an app and database on separate servers.
You can then make a simple NodeJS app to schedule that task and email the PDF. Or you can send these PDFs via your current Email Marketing tools.
Creating our script
Here is the dashboard we'll be exporting. We'll be running the scripts using Browserless, which requires an API, but they will also work in your own puppeteer-core
deployments.
To extract this dashboard, we can use the /function API to run the script below, where "token" is your API key from Browserless. The /function
API is a quick way to run commands without having to install any libraries on your end:
It's a simple script, we basically access the dashboard URL, login with our credentials, and click on the sign in button. Once the dashboard is loaded, we generate the PDF.
First we import the puppeteer-core
library, which is lightweight since you'll be connecting to a remote or existing chrome, and doesn't come with browser binaries.
We'll wrap all our code inside an async IIFE so that our code executes off the bat. Then we define our local variables, such as our API KEY, email, and password. The best practice here is to use process environments, but we'll keep it simple for now.
Now let's connect to the browserless WS endpoint by providing our API KEY and create a new browser and page to start automating.
Once that's done, we'll set the desired viewport
We then go to the browserless account page and wait for the network traffic to settle down so that the email and password selectors are actually loaded.
We enter our credentials and click on the submit button - you can use environment variables for the password here.
Once we've clicked log in, we want to wait to make sure the page is fully loaded by checking that the graph has been rendered.
Now we want to modify the page before generating the PDF. We can do so inside the page.evaluate() method. We are fetching the left panel navigation menu and removing it. Then we are finding the main panel that has the content that we want, we'll remove the .col-8
class and add the .col-12
class so that it is fullscreen. You can feel free to modify the UI of your dashboard in this section, such as removing unwanted sections or adding new graphic elements by injecting html+css that you may want to show in the PDF.
After all your modifications are done, feel free to generate the pdf. It is common that CSS defaults to print CSS styles (in order to save ink when printing) so you can add these two lines of code to make the CSS look more like a user would usually look at it. Otherwise the CSS could shift and look weird.
In some cases pages are rendering their fonts with web fonts, so if your page looks weird even after adding these two lines of code, it could be that the web fonts aren't loading properly because the page detects you're running chrome headless, and hence doesn't see the need to render any fonts at all. To overcome this, you can either run the session headful or set the user agent manually as so:
Note: for more info on reliably printing fonts, check out this article.
Here's an example of why setting these last two lines of code are relevant:
Page with only page.pdf(); looks like this:
Page with print background looks like this:
The first graph isn't rendering properly, so we'll use emulateMediaType set to screen to create our final result:
Now you can take care of sending this PDF through your marketing platforms, have fun!
Run your Puppeteer scripts with our browsers
If you need to scale our your exports, then try Browserless. We have a fleet of managed headless browsers, ready for use with any automation.
If you like this "Puppeteer PDF generator" article, you can check out how our clients use Browserless for different use cases: