puppeteer: footerTemplate and headerTemplate don't use body styles
Tell us about your environment:
Puppeteer version: 1.0.0 Platform / OS version: Linux Mint 18.3 Node.js version: 8.9.4
What steps will reproduce the problem?
I have a piece of code i use to generate pdf reports from html documents:
const page = await browser.newPage();
await page.goto(file, { waitUntil: "networkidle0", timeout: 100000 });
const default_options = {
format: "A4",
printBackground: true
};
const filename = `file-${uuid()}.pdf`;
const final_options = Object.assign({}, default_options, { path: filename }, options);
console.log(final_options);
await page.pdf(final_options);
await page.close();
file
is a link to a local html file. In this file head, I load specific fonts that I need for the document.
Inside of the options
, I pass the templates for headers and footers:
options: {
headerTemplate: "<p></p>",
footerTemplate: "<div class=\"footer\" style=\"font-size: 10px;color: #999; margin: 15px 0;clear:both; position: relative; top: 20px;font-family:my-font\"><p>Footer text</p></div>",
displayHeaderFooter: true,
margin: {
top: "100px",
bottom: "200px"
}
}
What is the expected result?
I would expect the footer to use the font loaded in the html body.
What happens instead?
The footer is looking into my system for the first font that could correspond the name provided and put this one instead. If the font is not installed on the system, it is using a default one.
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 89
- Comments: 49
I also noticed that if you stick a
style
tag in your header/footer templates, the CSS doesn’t all work right. Font sizes are different, custom font family is not changeable it seems, etc, it’s weird.This issue is not resolved.
Is it possible to use custom font family in footer template? I’ve tried adding <style> tags in the string and classes with styles in a styles.css file but nothing seems to work.
In-lining was the solution for me to get this to work. Thank to @kyriakos
Some initial failure notes to share:
The header and footer sections do not have any style at all. Everything must be defined.
And
Inlining CSS in footer / header works correctly. Its a workaround to do the trick for now till this issue is fixed.
We’re marking this issue as unconfirmed because it has not had recent activity and we weren’t able to confirm it yet. It will be closed if no further activity occurs within the next 30 days.
I have the exact same issue as described by @WalterWeidner
(node:13416) UnhandledPromiseRejectionWarning: Error: Page crashed! at Page._onTargetCrashed (…\node_modules\puppeteer\lib\Page.js:176:24) at CDPSession.Page.client.on.event (…\node_modules\puppeteer\lib\Page.js:138:56) at CDPSession.emit (events.js:182:13) at CDPSession.EventEmitter.emit (domain.js:442:20) at CDPSession._onMessage (…\node_modules\puppeteer\lib\Connection.js:233:12) at Connection._onMessage (…\node_modules\puppeteer\lib\Connection.js:119:19) at WebSocket.emit (events.js:182:13) at WebSocket.EventEmitter.emit (domain.js:442:20) at Receiver.receiverOnMessage (…\node_modules\ws\lib\websocket.js:720:20) at Receiver.emit (events.js:182:13)
NB: same css rule works well in the body of the pdf
Not being able to use custom font-family in the header and footer have significant impact: the generated pdf looks clumsy as different fonts are displayed depending of the zone (header, body, footer)
I’m using node.js 10.1.0 and Puppeteer 1.8.0
For now until the puppeteer lets us customize the header/footer I create this. It uses puppeteer and let fully customize header, footer, and pagination
https://github.com/PejmanNik/puppeteer-report#readme
@HosseinAgha I am using that. That’s not the issue. The actual document prints background just fine, but the header and footer part didn’t work the same way. It turned out to be a webkit issue. see https://github.com/GoogleChrome/puppeteer/issues/2182
TL;DR: add
-webkit-print-color-adjust: exact
to the header and footer stylesThere are related issues regarding
footerTemplate
visibility on all pages before the last page. The Footer is only visible on last page but invisible all pages before the last.See here with some explaining images: https://stackoverflow.com/questions/49985955/puppeteer-footer-only-display-on-last-page/49990697#49990697
Here’s the code to reproduce:
I am having the same issue.
@TylerJAllen yes, it is possible to do that. Your
<style>
tag is very likely working but it is referencing a font-family that is outside of its scope. Take a look at this snippet:In this example:
@sellerin I found a weird fix for the issue you are experiencing (outlined below) I too could not render the fonts using a full qualified path. The solution was to download the fonts then base64 encode them, put them inline and wrap another style sheet around it also base64 encoding that too. Fix: First download the .woff2 fonts that you require. Then base64 encode them. Then create an inlined style sheet like this: @font-face { font-family: ‘Libre Barcode 39 Extended’; font-style: normal; font-weight: 400; src: local(‘Libre Barcode 39 Extended’), local(‘LibreBarcode39Extended-Regular’), url(data:application/x-font-woff;charset=utf-8;base64,d09GMgABAAAAAA…AAA=) format(‘woff2’); unicode-range: U+0000-00FF, …; }
Then base64 encode this style sheet too, like this:
<style type="text/css"> @import url("data:text/css;base64,DQpAZm9udC1mYWNlIHs........"); </style>Insert this style sheet as inlined in the template. Now you can use the this style sheet in the header, body and footer e.g. .someClass { font-family: ‘Libre Barcode 39 Extended’; font-style: normal; font-weight: 400; font-size: 12pt; }
One other issue to mention. If I tried to use the above method in the header only it still causes the hang issue. I had to also use the same inlined style sheet in the body and I also had to use the same font too but setting the font size to 0 so it was not displayed.
Example here: https://github.com/Trejay/CssEmbeddedFonts
works pretty well for me.
footer.html
code
👍 same, setting footerTemplate and no footer shows up… 😦
This might help some, was trying to use Playwright with Chromium on OSX for PDF generation, sans-serif seemed to be ignored and gave me a serif default which was frustrating.
Changing “sans-serif” to “system-ui” gave me a sans-serif font i can live with, without having to load any specific fonts.
Maybe this will help, I was running my Puppeteer script as basic node script from the CLI (
node index.js
). The directory structure looked like this:Are you saying that the files need to be on the same domain as the page I am navigating to and then accessed relatively from there? For example if I navigated to https://example.com/about and my font was at https://example.com/fonts/font.woff I would put
url(/fonts/font.woff)
?Normally, that would make sense to me but these template sections don’t seem to play by normal rules.
I assumed it would be relative to the system I was running the script on since it looked like remote resources don’t seem to work (I tried https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lujVj9_mf.woff2, for example, and it didn’t work).
freegroup are you sure the font of your footer is 12px? I have noticed that the header and footer are scaleed like 1.4 times (all elements are bigger than defined - margins, padding, fonts etc.)
the solution is to insert the font as a base64. it’s working then. i tested with woff and woff2 formats, boths are working
Nice! I’ll have to try testing this out in our solution. Much better than base64 encoding the entire font.
Wow, this is a lifesaver. Works really well.
@Trejay your method helped me get the font to appear (although I had to use the TTF; WOFF/WOFF2 were ignored).
However, if I try to use ANY other font anywhere in the document, Page crashes. This happens whether in a CSS class or an inline style. Also, it seems that the custom font must be declared in the body selector, or Page will crash.
How exactly did you configure the body to use an additional font?
Yeah, still no dice @adelriosantiago. I added my test repo if you want to look: https://github.com/WalterWeidner/headless . The best I could do is install the font on the system and have Chrome pick it up from there.
Installing the google font as a system font as @WalterWeidner mentioned is the only way I was able to get custom fonts to work.
@seyfer puppeteer also crashes with me when I try to use font-face
On the other hand, I am using latest puppeteer 10.4.0 and just having any
<style>
tag infooterTemplate
makes it crash. So I tried Node js inline libraries, like Juice and inline-css. It works for all styles, except@font-face
, cause font-face has to be in<style>
tag infooterTemplate
and it leads to crash.Thank you!
@Trejay I actually followed your tip and it worked! Although, I started doing some trial and error by removing certain things and it turns out that you only need the font src as base64 and to have the font included in your main HTML as well as the header/footer. You don’t actually need to base64 encode and @import. At least not in my case. Thank you for your tip!
I still faced same problem. I used puppeteer 1.19.0. Node v12.6.0. If I set the footer like this:
await page.pdf({ format: 'A4', printBackground: true, landscape: true, displayHeaderFooter: true, headerTemplate: '<div style="display: none"></div>', footerTemplate: ' <html> <head> <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Tangerine"> <style> body { font-family: 'Tangerine', serif; font-size: 48px; } </style> </head> <body> <div style="width: 100%; text-align: right; -webkit-print-color-adjust: exact; margin-right: 20px;" > Page <span class='pageNumber'></span> of <span class='totalPages'></span> </div> </body> </html> ', margin: { top: 0, bottom: 60 }, });
it will crash. But, if I use this:
`await page.pdf({ format: ‘A4’, printBackground: true, landscape: true, displayHeaderFooter: true, headerTemplate: ‘<div style="display: none"></div>’, footerTemplate: ’ <style type="text/css" > @font-face { font-family: ‘Tinos’, serif; src: url(“https://fonts.googleapis.com/css?family=Tinos&display=swap”); }
the font style not working. Only font size and color that works
Just saying, but using web fonts will/can make the PDF somewhat 10 times larger since each character is rendered as a single SVG. You really should try to find the corresponding system font and install it. At least on Linux this works very well after some try and error. Also web fonts text can not be copy-pasted from the created PDF. Generally chrome has many problems of current/old phantomJS since they both are based on Webkit, so many phantomJS workarounds are working for chrome too.
@adelriosantiago I tried your solution for custom fonts and it doesn’t appear to work. I also tried using base64 encoded fonts but they crash the page. Any ideas?
@cyrus-za use
printBackground: true
optionIt seems like as @imanabu said inline styles only work for element types!
so you can’t write a new class and add it to your element you should use
div
,h1
, etc css rules.I also found out that the
font-family
only works using the<style>
tag. here is my workaround for changingfont-family
:I have built a template to solve the following problems:
@ovheurdrive theoretically you just have to pull the style tags out of the body and assign them to header, footer
Code
Maybe it helps, or is an drive for your own thoughts.