Skip to content

Custom Code Module (LiquidJS)

Write HTML, CSS, and LiquidJS in a Custom Code module or a custom line item column when ready-made modules are not enough.

This feature requires an Enterprise plan.

Quotivity Templates let you design most of a quote without writing code. When you need special behavior or data-driven layout, the Custom Code (Quotivity) module and custom columns let you write free-form HTML (with CSS) and LiquidJS. LiquidJS is a simple templating language very similar to HubSpot’s HubL.

If the change is mostly visual — fonts, colors, spacing, alignment, or column width — customize the HubSpot landing page CSS instead of rebuilding the content.

Surface What it is for Data you get
Custom Code (Quotivity) An entire quote section driven by your code The whole quote, including line items, contacts, company, and deal
Custom column One Line Items table column, rendered once per row The current line item as item, plus quote, company, and deal

A custom column is not a new HubSpot property and does not store a value. It renders from existing quote data each time the document is generated.

Both editors include an AI assistant that can draft or revise LiquidJS from a plain-language request. It understands LiquidJS and the native and custom HubSpot properties available in your portal. Start with a generated structure, then edit it. Review and preview the result with representative sample data before you publish.

LiquidJS is an open-source template language based on Shopify Liquid. It uses two kinds of markup.

Wrap a variable in double curly braces to display its value:

{{ quote.hs_quote_amount }}

Transform values with filters after a pipe:

{{ quote.hs_quote_amount | money }}

Filters change how a value is shown — for example, making text uppercase, formatting a date, or adding a suffix.

Tags use {% and %} for conditions and loops.

Conditionals:

{% if deal.amount > 10000 %}
<p>Thank you for this significant investment.</p>
{% else %}
<p>Thank you for your business!</p>
{% endif %}

Loops:

{% for item in line_items %}
<p>{{ item.name }}{{ item.price | money }}</p>
{% endfor %}

The include, render, and layout tags that LiquidJS usually supports are not available in Quotivity templates.

Tokens map to HubSpot property names on objects related to the quote. Type {{ in the editor to open auto-complete, choose an object, then choose a property.

Namespace What it contains Example
quote Quote-level properties quote.hs_title
line_items All line items on the quote line_items[2].hs_sku
contacts Contacts associated with the quote contacts[0].firstname
company The first associated company company.name
deal The first associated deal deal.dealname
fees Fees on the quote fees[0]
users Users related to the quote users[0]

Custom column code runs once per row:

Namespace What it contains
item The current line item
members When the row is a bundle header, the bundle’s included (non-optional) member line items; empty for other rows
quote Quote-level properties
company The first associated company
deal The first associated deal

Use members to summarize a bundle on its header row — for example, list every included product without displaying the member rows themselves:

{% for member in members %}
<div>{{ member.name }} × {{ member.quantity }}</div>
{% endfor %}

Optional line items in the bundle are not part of members, matching the “Included Products” bundle display.

Missing properties render as empty values. Unknown Liquid filters cause a syntax error. Invalid Liquid in a Custom Code module renders no content for that section; invalid Liquid in a custom column leaves that cell empty.

Filter Example output
money $1,299.00
money_with_currency $1,299.00
money_without_currency 1299.00
money_without_trailing_zeros $1,299
parse_currency Strips currency symbols and returns a number
{{ item.price | money }}
{{ item.price | parse_currency | plus: 50 | money }}

You can pass a currency code and locale, for example {{ item.amount | money: "USD", "en-US" }}. Standard LiquidJS filters such as upcase, downcase, append, truncate, and default are also available.

Use default when a property might be empty:

{{ item.hs_sku | default: "N/A" }}

Use the LiquidJS date filter with a format string:

Filter Example output
date: '%B %-d, %Y' January 1, 2026
date: '%B %d, %Y' January 01, 2026
date: '%m/%d/%Y' 01/01/2026
Purpose Token Meaning
Year %Y 4-digit year, e.g. 2026
Year %y 2-digit year, e.g. 26
Month %m 01–12
Month %b Abbreviated month, e.g. Jan
Month %B Full month, e.g. January
Day %d 01–31
Day %-d / %e Day without a leading zero
Weekday %a Abbreviated weekday, e.g. Mon
Weekday %A Full weekday, e.g. Monday
Time %H 00–23 hour
Time %I 01–12 hour
Time %M Minute (00–59)
Time %S Second
AM/PM %p / %P AM or PM / am or pm
Timezone %z / %Z Offset or abbreviation
{{ quote.hs_expiration_date | date: '%B %-d, %Y' }}
  1. Open the template in Quotivity Studio.
  2. Click Edit Design to open the HubSpot landing page.
  3. Add the module. Click +, search for code, and drag Custom Code (Quotivity) onto the page.
  4. Publish the landing page, then return to Quotivity.
  5. Select Custom Code in the module panel.
  6. Write or generate the code. Optionally describe what you want in the AI assistant, then edit the LiquidJS in the editor.
  7. Check the syntax indicator below the editor, then save. The live preview updates immediately.

Use Custom Code for a complete custom section. For one value in each line item row, use a custom column instead.

<section class="proposal-summary">
<h2>{{ quote.hs_deal_name }}</h2>
<ul>
{% for item in line_items %}
<li>
{{ item.name }}{{ item.amount | money }}
</li>
{% endfor %}
</ul>
</section>

Output is sanitized before a buyer sees it. Scripts, event-handler attributes, and unsafe markup are removed. This module is for generated HTML, CSS, and Liquid logic — not client-side JavaScript. Put reusable styling on the HubSpot landing page; inline style attributes are fine for small, module-specific adjustments.

Adding a custom column to the Line Items table

Section titled “Adding a custom column to the Line Items table”
  1. Open the template and select the Line Items module.
  2. Go to the Columns tab.
  3. Open the column picker and click Add Custom Column.
  4. Rename the column by clicking its label.
  5. Click the code icon to open Custom Column Code.
  6. Write or generate LiquidJS using item, quote, company, and deal.
  7. Check the syntax indicator, click Done, then save the module.
{{ item.price | money }}
{% if item.hs_discount_percentage %}
<small>{{ item.hs_discount_percentage }}% discount applied</small>
{% endif %}
  • Custom column code runs once per line item — use item for the current row.

  • The AI assistant knows the properties in your HubSpot portal, so you can describe the result in plain English.

  • You can also paste code into another AI tool if you want a second pass on LiquidJS syntax.

  • Custom Code is not only LiquidJS; it also accepts standard HTML and CSS.

  • To inspect available data while drafting, temporarily add:

    <pre>{{ quote | json: 2 }}</pre>

    That dumps the quote object in a readable form. Remove it before you publish.