Adding a header or footer to your document

Important caveats

Due to limitations in our PDF engine (based on Chromium) header and footer defined in the settings

  • cannot load external resources like images, CSS or fonts over HTTP

  • do not display accented characters correctly by default

  • cannot execute JavaScript code

  • cannot be skipped on the cover page

Working around caveats

Here are some workarounds for the main header/footer caveats. You can also chose to try our experimental alternative below which provides much more power but can come at a cost.

Using images and CSS

Since you can't load images or CSS content over HTTP, you will need to inline them.

For images you can use the data-uri format to insert them in the content.

For CSS you will need to inline it in a <style> tag.

You can learn how to inline fonts in our dedicated documentation page.

Displaying accented characters

For some strange reason the header and footer content are not rendered using UTF-8. That said we do have solutions.

Rendering fixed text correctly

For fixed content, you can simply replace accented and special characters with their HTML Entity counterpart. For instance é would be replaced with &eacute;.

Rendering text coming from dynamic data

Doing the search & replace work yourself would be no fun or even impossible in some cases. For this reason, we provide a Liquid filter called entities that will do the work for you.

{{"Marie Skłodowska Curie" | entities}}
<!-- Marie Sk&lstrok;odowska Curie -->

Executing JavaScript

Sadly, there's no workaround for this.

Skipping on the cover page

Sadly, there's no workaround for this.

Two types of Documents

After making a lot of Templates for ourselves and for our clients, we've divided Templates into two categories: Powerpoint-like and Word-like. Depending on the type of Document you're making you might want to consider different approaches.

Powerpoint-like Documents

You can consider a Document as Powerpoint-like when it's only composed of individual pages and content is always fixed to a given page.

A good example for this would be a personalised book for children. Each page is always the same and only a few pieces change from one book to another Another good example is a performance report where you have charts and their descriptions. Each chart is always on the same page, only the content changes but not the size it takes on a given page.

Our recommendation

While you can still define your header and footer in your Template settings, we recommend you consider including them in your content directly.

Since you control each page and how it's organised, it's a lot simpler to make the header and footer part of the content. They will get the same styles as the rest without needed any tricks.

The only trick you will need is about displaying the current page number but we got you covered in our dedicated documentation page.

Word-like Documents

Those Documents have a content that flows from page to page. You can think of it like a Word document for a contract or a text-heavy report.

Our recommendation

For this type of Document. You need to use the header and footer fields in the Template settings as their content cannot be included directly in the HTML tab.

You can choose between very basic content using the three default field available or switch to the advanced mode and write custom HTML, including some styles.

Don't forget to set margins

In order for the header or footer content to show, your Template needs to have top and/or bottom margins.

Printing the page number and total pages

You can use two magic tags in your header/footer from the Settings tab:

[page] will print the current page number [topage] will insert the total number of pages

If you use the Advanced header/footer you will need to use the following HTML tags instead:

<span class="pageNumber"></span> will print the current page number <span class="totalPages"></span> will insert the total number of pages

Mind the margins

If you find yourself adding a [page] or [topage] tag and it does not appear. It could be that the engine thinks there's not enough room to display it. Try augmenting the margins in the Settings and see if it works.

You can use dynamic data

Header and footer advanced content do accept dynamic data but you may need some help from the entities filter for accented characters like mentioned earlier.

Experimental solution

Paid account only

Including JavaScript based on their URL is only possible on a paid account. Documents including external JavaScript files will fail on a free account.

We know that the header and footer huge caveats are a real pain point when it comes to authoring Templates. So we've been looking for solution that we could integrate directly into PDFMonkey at some point.

We're not there yet but we do have an experimental solution, using a great JS library call Paged.js. It opens up a lot of cool features like having table of contents or great headers & footers.

How to use it

The first step is to define what our header and footer will look like. Let's start by defining two div elements in our HTML tab. For good mesure, we'll also add a div showing where our content starts.

HTML
<div id="pageHeader">
  <div class="header-content">
    <img src="https://placekitten.com/60/60" />
    <div>Header Text</div>
  </div>
</div>

<div id="pageFooter">
  <div class="footer-content">
    <div>Footer Left</div>
    <div>Footer Right</div>
  </div>
</div>

<div class="content">CONTENT STARTS HERE</div>

Now we need to import the Paged.js script:

HTML
...

<div class="content">CONTENT STARTS HERE</div>

<script src="https://cdn.jsdelivr.net/npm/pagedjs@0.3.5/dist/paged.polyfill.js"></script>

It won't look nice until we define some styles to go with it.

Let's start by defining our two divs as "running elements" so that we can call them later on.

CSS
#pageHeader {
  position: running(pageHeader);
}

#pageFooter {
  position: running(pageFooter);
}

And now we can also style the content inside those two elements and our content:

CSS
.header-content, .footer-content {
  align-items: center;
  background: #1f2937;
  color: #fff;
  display: flex;
  /* Notice that we set a specific height here */
  height: 80px;
  justify-content: space-between;
  padding: 0 30px;
}

.content {
  text-align: center;
}

The last missing piece is instructing Paged.js about where to insert the elements so they can become actual header and footer:

Careful!

Unless you use the Tailwind CSS 3 Javascript CDN, the code below MUST be in the CSS tab and not in a <style> tag in the middle of the HTML tab, otherwise it will not work.

@page {
  /* Pixel size for a portrait A4 page */
  size: 793px 1120px;

  /* We're using the same height as the height we defined
     for the header/footer content above */
  margin: 80px 0;

  /* This is where we tell Paged.js where to display
     our elements */
  @top-center { content: element(pageHeader); }
  @bottom-center { content: element(pageFooter); }
}

Names matter

Notice how we're referring to the same names as defined earlier. If we had set running(superHeader) for the header we should be calling element(superHeader) here too.

Page size in pixels

For this example we used the portrait A4 format so you would need to adapt the size property to your page size. You can find a list of all the default sizes in pixels in our documentation.

Table headers

Paged.js is known to break multi-page tables with headers. If this is the case for you, this Github Gist might help you.

And here is the end result!

To learn all the great things you can do with Paged.js, visit their documentation about Generated Content in Margin Boxes.

Last updated