Vercel is a hosting platform, powered mostly by NextJS, to deploy and scale your Node and TypeScript applications. As with many hosting providers this comes with its limits and caveats. When wanting to do actions with headless Chrome and puppeteer on Vercel and you'll likely immediately run into a few issues regarding size and memory limits which make it tough to use puppeteer effectively. Below we detail how you can get around these issues easily with browserless. You can also check out our example project here.
Best practices and setting up
Before we dive too far into it, we'll need to cover a few pre-requisites here. Don't worry, we'll have examples of each including a demo repo to get you started!
- We're using NextJS as our main technology since it's incredibly effective and popular for Vercel deployments.
- You should be somewhat familiar with how environment variables work in NextJS to properly store secrets. Feel free to read more here.
- For the purpose of this blogpost we'll create a simple route that generates a PDF of a URL. Feel free to alter this, but it'll be enough to get you started!
Setting up Puppeteer for Vercel
If you're working on something entirely new then you can simply run the following command, answer a few questions, and get a demo app set up very easily. The command is:
$ npx create-next-app@latest
This command will create your basic "Hello World" app and then exit. For NextJS apps in particular, you'll likely have a "pages" directory with an "api" folder as well. This is where we'll be spending most of our time since our functionality is created inside the NodeJS environment.
Once your application is set up then we'll also install Puppeter since it is required by Vercel in order to deploy properly. We'll opt for the 'puppeteer-core' module to avoid the first issue in Vercel: the 50MB file-size limit. Puppeteer by default ships with headless Chrome bundled together, which is easily over 50MB in size. By using 'puppeteer-core' we can get around this by only having puppeteer's code installed and not the browser binary. To install Puppeteer for Vercel, simply do the following:
$ npm i puppeteer-core
Writing our Puppeteer API
Next we'll set up our API handler to generate these PDFs. By default NextJS adds a "/api" path pre-pended to whatever our route's name is. For this post, we'll have a "pdf.ts" route in the "pages/api" directory. We'll explain everything below but here's the code to get started:
To get started we import some type information for NextJS and then import the puppeteer module from puppeteer-core. The typings aren't required if you're using plain NodeJS, so feel free to delete those in that case.
Next is a "Json" type to describe our responses back to the client. Since our handler can convert any URL into a PDF we need to make sure users supply one! Feel free to alter this block to fit your use-case or needs with puppeteer.
Finally we have our route file. This handler will check to see if there's a "?url" query-parameter for the site to convert to a PDF. If it's missing we'll return a 400 message and a response indicating that it's required. After that we simply connect to a live browser on browserless, create a page, and generate that PDF.
Making puppeteer work on Vercel with browserless
The reason we're able to get puppeteer and Chrome working on Vercel is by avoiding having to download and run Chrome inside of our Vercel app. Separating your puppeteer code from Chrome is actually a great best practice as it cleanly separates Chrome from your application code. Think of it like a database: you don't want to have your database and application code co-located on the same machine ideally.
In order to connect to browserless and use headless Chrome you'll need to get an API token. We offer free accounts with no credit card required here. Once you have your API key, you'll want to create an env.local file with it:
Now that that's set up, let's start our application and visit the route to see if it works properly. From the root of the project, run the following command. You'll want to restart this as any environment variable changes do require a restart of the dev server:
npm run dev
Then, once it's up and ready, go to http://localhost:3000/api/pdf?url=https://www.browserless.io/docs/start. You should get a PDF file downloaded!
Deploy your Puppeteer Code on Vercel
Once we've verified everything is working properly, the next step is getting our Puppeteer + NextJS application onto Vercel. There's two ways of doing this: either the Vercel CLI or via Github. For now we'll use GitHub as a deployment method. You'll want to create a new app on Vercel by clicking "Create a New Project":
This will prompt you for a few options, but we'll want to deploy from GitHub. After adding access here's the permissions and screen grab of our GitHub selection:
Vercel should automatically recognize that this is a NextJS application, which means we won't have to inform it how to build or bundle Puppeteer, npm run build
, or anything else. We will want to input our browserless token, however, as it's necessary for browserless to work:
Once in you'll click "Add" then "Deploy." After a few seconds your page should load and display their "Hello World" Screen since we never altered it:
From here you can edit the page's URL and add "/api/pdf?url=https://example.com" to it. This will verify that our Puppeteer code on Vercel works swimmingly!
Closing thoughts
Using Puppeteer on Vercel doesn't have to be a chore. With browserless you can easily get past any file-size limits, memory limits, and have a great developer experience without the headache. Feel free to sign-up for a hosted account and get started today, or check out our example repo here. Happy Coding!