Open EbubeEvan opened 8 months ago
Hey @EbubeEvan, could you confirm what version of react-print-pdf
you are using? There have been improvements to running Tailwind server-side in the latest versions.
Hi @Titou325 I'm not sure as I had already uninstalled it before raising the issue. But I know it was the latest version as of March 10th when I installed it.
Hey @Titou325,
I will make an assumption here, but it might be related to the fact that Vercel runs on Lambdas.
Puppeteer relies on Chromium, which is way to large to run on Lambdas, but by using @sparticuz/chromium
and puppeteer-core
on production
it will run smoothly.
I created a server action, but can also perfectly run on a route handler.
"use server";
import { Browser } from "puppeteer-core";
export async function makePDF(html) {
let browser: Browser | undefined | null;
if (process.env.NODE_ENV !== "development") {
const chromium = require("@sparticuz/chromium");
const puppeteer = require("puppeteer-core");
browser = await puppeteer.launch({
executablePath: await chromium.executablePath(),
headless: chromium.headless,
ignoreHTTPSErrors: true,
defaultViewport: chromium.defaultViewport,
args: [...chromium.args, "--hide-scrollbars", "--disable-web-security"],
});
} else {
const puppeteer = require("puppeteer");
browser = await puppeteer.launch({
headless: "new",
});
}
if (browser) {
const page = await browser.newPage();
await page.setContent(html);
const pdfBuffer = await page.pdf({
format: "a4",
printBackground: true,
margin: {
top: 80,
bottom: 80,
left: 80,
right: 80,
},
});
await browser.close();
return pdfBuffer;
}
return null;
}
Route handler:
import { compile } from "@onedoc/react-print";
import { PdfCv } from "../_components/pdf-cv";
import { makePDF } from "../actions/make-pdf";
export async function GET(request: Request) {
try {
const headers = new Headers();
const html = await compile(<PdfCv />);
const pdfBuffer = await makePDF(html);
headers.append("Content-Type", "application/pdf");
headers.append(
"Content-Disposition",
`attachment; filename="resume-${new Date().getFullYear()}.pdf"`
);
return new Response(pdfBuffer, { headers });
} catch (error) {
return new Response("Error downloading PDF", {
status: 500,
headers: {
"Content-Type": "text/plain",
},
});
}
}
You will also need to update your next.config.js
file with the following.
experimental: {
serverComponentsExternalPackages: ["puppeteer-core", "@sparticuz/chromium"],
},
Hey @thebiltheory, thanks for these detailed examples! If using Onedoc as a backend, you don't actually need to run puppeteer as the payload is sent externally for rendering.
This issue originally came from our
There is another consideration when running on Vercel regarding the functions timeout as PDF rendering can be slow, sometimes exceeding the default invocation time of 15s. This timeout can be changed for paid customers, and we are releasing speed improvements regularly.
Thanks!
@Titou325 this is only if you use react-print
to put the PDF together.
I personally don't use Onedoc to render the PDF, also the Error 500
on Vercel doesn't say much, so I'm just assuming this could be one of the reasons if you only use react-print
on the frontend.
Makes sense, do you still use the tailwind component or has it been switched to plain css as well?
@Titou325, I use tailwind yes, also I believe Onedoc compiles everything to css?
I'm not even sure I need Tailwind
. Will check.
I had to switch to react-to-print to download pdfs. which was a bummer cos I then had to display the document on the DOM which I didn't want. I also couldn't generate a pdf link to send via email. I really wish react print worked for me.
Note that the latest versions of react-print do work on Vercel, with the main caveat being that RSC (use client/use server) cannot be used. This is easy with the pages
router, however with the app
router, RSC is the default pattern. A common workaround is to expose 2 routes, one with the page and the other one with the call to Fileforge.
The API route calls the Page route to get the rendered HTML from React, and this is passed.
While non-ideal, this is currently hard to bypass as Next monkey patches React's rendering functions.
An issue is open with Next at https://github.com/vercel/next.js/issues/68150
When I hosted my Nextjs 14 website on vercel, I was generating the pdf on a server component using tailwincss in the pdf template component.
It worked well on my computer but was throwing errors when hosted. I then changed it to generate on the backend using a route handler and I got an error saying that a particular tailwindcss module couldn't be found.
I changed the styling to plain CSS and I got a status 500 error. All this time, it worked perfectly on my computer so I wonder why it doesn't work when hosted on vercel.