HTML/CSS Templates

In addition to uploading an existing PDF, you can create a new template using HTML and CSS.


DocSpring uses a CSS extension called SASS. SASS comes in two flavors, but we use the one that is compatible with standard CSS (SCSS).

This means that you can paste in any CSS, and it will Just Work™. SCSS also supports some powerful features, including variables and nested rules. Take a look at the SASS Guide to learn more.


HTML templates use the Liquid markup language. This allows you to insert field values into your HTML. You can also add advanced logic, such as conditions and loops.

Learn more about Liquid.

Referencing Fields

Use the {{ }} syntax to insert a field value in your template.

If you have a field called "name", you can render that value in your template like this:

<h2>{{ name }}</h2>

Use a dot to access nested fields, and square brackets for arrays:

<h2>{{ }}</h2>
<h2>{{ names[2] }}</h2>

Liquid Filters

When you upload an existing PDF, our template editor includes features such as date formatting, formulas for numbers, "uppercase" for text fields, etc. These features have been removed from our HTML template editor, because these can be achieved by using Liquid "filters".

For example, you can use the upcase filter to convert text to uppercase:

<h2>{{ full_name | upcase }}</h2>

See the Liquid Filters page for more information about available filters.

Please contact us if you would like us to add a new Liquid filter.

Note: DocSpring supports most of the Liquid filters that you can find in the Liquid documentation. However, you may find some third-party articles and documentation that reference filters that we don't support. For example, Shopify provides some custom liquid filters that are specific to Shopify stores.


You must use the {% signature %} Liquid tag to render signatures in your HTML template. Signatures can be provided as either an image, or text (e.g. the user typed their name and selected a font). The signature tag will handle both of these cases:

{% signature signature_field %}

Behind the scenes, image signatures will be rendered in an <img> element with a signature-image class:

<img class="signature-image" src="data:image/png;base64,..." />

Text signatures will import the required typeface, and render the name inside an <span> element with a signature-text class:

  style="color: black; font-size: 16px; font-weight: normal; display: inline-block; font-family: 'Dancing Script';"
  John Smith

You can pass the following options to the signature tag, to control the width and height of image signatures, or the font size and weight of text signatures. (These options are added as inline CSS styles.)

Option Signature Type Default Value
width Image (from image)
height Image (from image)
font-size Text normal
font-weight Text 16px
color Text black

There is also a preview_type option, which allows you to control the type of signature that is shown in preview PDFs. We show a image signature by default. Use preview_type: text to show a text signature.


{% signature signature_field, width: 300px %}
{% signature signature_field, preview_type: text, font-size: 24px, color: #333


You can upload static images under the "Images" tab. Use the template_image_url tag to get the image URL:

<img src="{% template_image_url IMAGE_ID %}" />

To include an image or signature field (i.e. submitted in an API request), you can use the field value as the src attribute for an img tag. This will refer to an internal URL for the image:

<img src="{{ photograph }}" />

If you have an optional image field, you should use a condition in case the image was not provided:

{% if photograph %} <img src="{{ photograph }}" /> {% endif %}


You can use the date filter to format a date field:

<h2>{{ date | date: "%B %-d, %Y" }}</h2>

You can use the special "now" string to get the current date and time:

<h2>{{ "now" | date: "%B %-d, %Y" }}</h2>

We also support an in_time_zone filter that allows you to convert dates and times into different timezones:

<h2>{{ "now" | in_time_zone: "America/New_York" | date: "%B %-d, %Y" }}</h2>

Here is a list of all timezones that you can use with the in_time_zone filter.

Page Breaks

You can force content to start on a new page by using the page-break-before CSS property.


.new-page {
  page-break-before: always;


<p class="new-page">This paragraph will start on a new page.</p>

View documentation for the page-break-before, page-break-after, and page-break-inside properties.

Headers and Footers

You can add a header or footer to each page in the "Header HTML" and "Footer HTML" tabs. CSS from the SCSS tab also applies to headers and footers.

You can use the pageNumber and totalPages classes to show the current page number and total pages. The following example shows how to add a footer with page numbers (e.g. Page 1 of 2):

  style="display: block; margin: 0 40px; padding-top: 3px; width: calc(100% - 80px); border-top: 1px solid #aaa; color: #aaa; text-align: right;"
    Page&nbsp;<span class="pageNumber"></span>&nbsp;of&nbsp;<span

Here's how the footer will look at the bottom of the PDF:

Footer Example

Generating PDFs

Once you've set up your template and added your fields, you can generate a PDF by either filling out the web form, or making an API request.

results matching ""

    No results matching ""