Closed SawkaDev closed 2 years ago
After more investigation it seems related to how PDFMake takes in a absolute file path. When using NextJS and you are doing server side generation this issue happens.
Hello @Sliffcak
I have a similar issue on Heroku with nodejs/express.
Somehow the default standard fonts seem to work. See here
const fonts = {
Times: {
normal: 'Times-Roman',
bold: 'Times-Bold',
italics: 'Times-Italic',
bolditalics: 'Times-BoldItalic',
},
};
While this does not work
Roboto: {
normal: path.resolve(dirname, './fonts/Roboto/Roboto-Regular.ttf'),
bold: path.resolve(dirname, './fonts/Roboto/Roboto-Medium.ttf'),
italics: path.resolve(dirname, './fonts/Roboto/Roboto-Italic.ttf'),
bolditalics: path.resolve(dirname, './fonts/Roboto/Roboto-MediumItalic.ttf'),
};
Oh my....lord. Thank you so much. I will just deal with the default fonts for now. This was in my face the whole time, Trust the docs!
But seriously, I think there needs to be better documentation on either pdfmake or nextjs side to help with custom fonts.
And throwed error is?
Sadly this error is now a bigger problem. I was going to just use the standard fonts but I see they do not support special characters like less than or equal to symbol.
@liborm85 I can not get anywhere to show me an error code. I just keep getting Error: AxiosError: Request failed with status code 501
on the front end.
I am trying to do server side pdf generation only.
@liborm85 It works on localhost but when I deploy to vercel the PdfPrinter is not able to work. I do not see any useful errors or prints. Is there a way to turn on verbose printing for pdfmake?
@liborm85 can I get this back open for now (seems eve @Ebaneck is having the same issue)? the official error I am geting in vercel is the following.
{"errno":-2,"syscall":"open","code":"ENOENT","path":"/assets/fonts/Roboto-Bold.ttf"}
Seems vercel can not locate the static file. I tired all sorts of combinations with the file path and it still gave this error without the beginnign slash
{"errno":-2,"syscall":"open","code":"ENOENT","path":"assets/fonts/Roboto-Bold.ttf"}
When i check the source in vercel I see the following, that path should exist right?
Here is the file directory structure in development / localhost:
The error appears after this function gets called
const pdfDoc = printer.createPdfKitDocument(docDefinition);
I think that might be related to wherever you can import static files under public/
in the code.
I'm not familiar with Next.js but am facing similar issue with fonts and images using SvelteKit which calls Vite under the hood. And Vite's docs says assets in public/
cannot be imported in the code. Don't know if the same applies to you.
The problem is if I put the assets outside the public/
, they won't appear in the build/
dir after building, which is uploaded to hosting. If I put them inside public/
, I think the code cannot import them as mentioned above. For images I also tried writing the public URL like https://my-domain.com/img/hello.jpg
(which I checked is accessible), but appears public URLs are not supported in server-side per pdfmake's docs. For fonts there're even fewer documented options server-side.
I made it work on Netlify by passing my font files to the included_files
option in the netlify.toml
config file. On Netlify, SvelteKit endpoints are hosted as serverless functions. Turns out Netlify has provided the above option to specify additional files (which are not import
ed explicitly) to be accessible in serverless functions.
Helpful example for Netlify: https://kisaragi-hiu.com/kemdict-sveltekit-sqlite.html
I haven't try the same on Vercel, but I'm under the impression they also convert your code into serverless functions. And they do have a includeFiles
option in vercel.json
which looks like the above counterpart on Netlify (though I'm not sure what should the glob path be, to represent your SvelteKit endpoint). I think you may experiment with it, and in the worst case perhaps try Netlify if you can't make it work on Vercel.
Anyone found a fix yet? Have tried the URL method & VFS method for adding new fonts, I get the same 405 Axios error anytime I add any logic for custom fonts, though everything works fine if i make everything default, tried the .ttf files themselves, the base64 encoded version and them hosted at URLS. Using Vercel & next.js.
Tempted to find another library and or just stick with default fonts. Very frustrating
I made it work on Netlify by passing my font files to the
included_files
option in thenetlify.toml
config file. On Netlify, SvelteKit endpoints are hosted as serverless functions. Turns out Netlify has provided the above option to specify additional files (which are notimport
ed explicitly) to be accessible in serverless functions.Helpful example for Netlify: https://kisaragi-hiu.com/kemdict-sveltekit-sqlite.html
I haven't try the same on Vercel, but I'm under the impression they also convert your code into serverless functions. And they do have a
includeFiles
option invercel.json
which looks like the above counterpart on Netlify (though I'm not sure what should the glob path be, to represent your SvelteKit endpoint). I think you may experiment with it, and in the worst case perhaps try Netlify if you can't make it work on Vercel.
Having the same issue in Astro (endpoint), I tried a lot of combinations for paths too, using the path
module, using import.meta.dirname
in combination with path.resolve
, etc, locating fonts in public
and somewhere inside my project, none worked.
As mentioned above I guess files can't be read from the public
directory, I've checked the output source in vercel and the fonts files are there, even though my paths are ok it doesn't work on vercel, only localhost.
I tried adding the includeFiles
option inside the vercel.json
config but the deploy is failing.
I get the following message:
No solution seems to work. Also tried the vfs
fonts approach.
This didn't worked for me in Astro, it may work in Next.js or Sveltekit:
vercel.json
{
"functions": {
"api/route.js": {
"includeFiles": "./src/dir/to/folder/**/*"
}
}
}
https://vercel.com/guides/how-can-i-use-files-in-serverless-functions#using-dynamic-require
Tried this in Astro, didn't work...
astro.config.mjs
export default defineConfig({
output: "hybrid",
integrations: [
svelte(),
],
adapter: vercel({
includeFiles: [
"./src/factory/pdf/resources/fonts/Roboto-Bold.ttf",
"./src/factory/pdf/resources/fonts/Roboto-Regular.ttf",
"./src/factory/pdf/resources/fonts/Roboto-Italic.ttf",
"./src/factory/pdf/resources/fonts/Roboto-BoldItalic.ttf",
],
}),
});
https://docs.astro.build/en/guides/integrations-guide/vercel/#includefiles
Hi All,
I am generating a PDF on the server side then sending back to client. In localhost it works fine, once i deploy to Vercel (nextjs) I get an error.
Server Code:
const fonts = { Roboto: { // Path relative to process.cwd() normal: 'src/pages/api/fonts/Roboto-Regular.ttf', italics: 'src/pages/api/fonts/Roboto-Italic.ttf', bold: 'src/pages/api/fonts/Roboto-Bold.ttf' } }; const printer = new PdfPrinter(fonts); const docDefinition: TDocumentDefinitions = await generateDocDefinition(patient); const pdfDoc = printer.createPdfKitDocument(docDefinition); pdfDoc.pipe(BlobStream()); pdfDoc.end(); res.send(pdfDoc);
On Client:
const generatePDF = async (id: string) => { await apiClient .get(`/patient/generatePDF/${id}`, { responseType: 'blob' }) .then((response) => { const file = new Blob([response.data], { type: 'application/pdf' }); //Build a URL from the file const fileURL = URL.createObjectURL(file); //Open the URL on new Window window.open(fileURL); }) .catch((error) => { console.log('Error: ' + error); }); };
In deploy environment it is hitting the catch block.
Did you resolve the issue? I keep my fonts in /public
directory. On localhost, I am able to load fonts using public/fonts/abc.ttf
but this doesn't work in Vercel.
Vercel uploads static files to .vercel/output/static
and are available from the root URL of your deployed app, so e.g your-app-name.vercel.app/fonts/abc.ttf
. But now the problem is that pdfmake tries to load file from a local file URL when running server side so it fails to load fonts from a network URL.
ALSO, how were you able to run pdfkmake in a NextJS api route in the first place? I made a simple route in NextJS (app router) API like /api/preview. I send a dummy response to test, it works fine. I try generating pdf from the router handler, add multiple logs, call the endpoint - I get 404, no logs show up anywhere. I go back to dummy response, it works fine on the exact same endpoint. That doesn't make any sense to me at all. :|
So I made a monorepo with a small Express app just for the pdf generation. Finally was able to get server up and running with my NextJS app but now the fonts are not loading.
I realized that I don't need and shouldn't be putting my fonts in the public directory for my apps' specific use case and ended up doing this to load fonts in my ExpressJS app hosted on Vercel.
{
EBGaramond: {
normal: path.join(__dirname, "/fonts/EBGaramond-Regular.ttf"),
bold: path.join(__dirname, "/fonts/EBGaramond-Bold.ttf"),
},
SFPro: {
normal: path.join(__dirname, "/fonts/SF-Pro-Text-Regular.otf"),
bold: path.join(__dirname, "/fonts/SF-Pro-Text-Bold.otf"),
}
}
This works perfectly locally and in deployment.
Hi All,
I am generating a PDF on the server side then sending back to client. In localhost it works fine, once i deploy to Vercel (nextjs) I get an error.
Server Code:
On Client:
In deploy environment it is hitting the catch block.