Last modified: August 22, 2025
HubSpot’s CMS uses the HubSpot Markup Language, referred to as HubL (pronounced “Hubble”). HubL is HubSpot’s extension of Jinjava, a templating engine based on Jinja. HubL uses a fair amount of markup that is unique to HubSpot and does not support all features of Jinja.
This article will take you through the basics of HubL’s features and syntax.
Types of delimiters
Similar to other commonly used templating languages such as PHP, HubL can be mixed into your HTML in coded templates files or HubL template modules. In order to differentiate, where your HubL starts and ends, you will need to learn a few key symbols that act as delimiters.Statements
{% statement %}
HubL statements are used to create editable modules, define conditional template logic, set up for loops, define variables, and more. Statements are delimited by {%
. They do not print anything to the page.
Expressions
{{ expression }}
Expressions print values stored in the context of the template. Expressions are delimited by {{
. For example, a variable must be defined as a statement, but then a HubL expression would be used to print the variable.
Do tag
{% do %}
The ‘do’ tag works like a statement, and can be used to modify lists and dictionaries.
- HubL
- Output
Comments
The final type of delimiter that you may encounter or decide to employ while developing with HubL, is a HubL comment. Comments are delimited by{#
/ #}
.
Be mindful of nesting comments in your code, as it can result in the trailing comment tag to render as text.
Modules
Modules are dynamic areas of a template that can be customized by the end user in the content editor. For example, if you were coding a template file from scratch, you would add modules to templates with HubL tags, to give your content creators the ability to edit areas of the page. Module tags are made up of the following components:- Type of module: specifies which module to render. Please refer to the HubL Supported Tags page for a listing of the different types of modules available.
- A unique name for that module: gives the module a unique identity in the context of the template.
- Path: depending on the tag, defines the location of where the module is in the design manager. The path for HubSpot default modules should always start with @hubspot/ followed by the type of module. See the example below and the using modules in templates page for more.
- Parameters: optionally specify additional module information.
- HubL
- Output

Variables and macros
HubL includes many predefined HubSpot variables that print their helpful values from the app. In addition, you can define your own variables in a template. In the following example, a variable namedprimaryColor
is defined in a statement and then printed with a HubL expression. This example mixes the HubL variable with CSS.
- HubL
- Output
- HubL
- Output
Filters and functions
You can alter and transform values of template variables using HubL filters, which are specified using a|
pipe character followed by the filter name. A simple example displayed below is formatting a date variable.
In the example below, assume a blog post was published on the 29th of April. The publish date of the post is formatted with a datetimeformat
filter.
- HubL
- Output
- HubL
- Output
If statements
If statements allow you to use conditional logic to dictate how your template will render conditional logic in HubL statements forif
, elif
, else
, and endif
. An if statement must begin with an if
and end with an endif
.
The example below defines a choice module that lets users in the content editor select a department from a dropdown menu. Depending on what the user selects in the editor, the template will generate a dynamic heading for a careers page. This example requires the use of the export_to_template_context
parameter.
For loops
For loops allow you to iterate over items stored in a sequence. They will most commonly be used with rendering blog content in a listing format. For loops begin with afor
statement and end with an endfor
statement.
In the example below, an array of types of bears is stored as a variable called bears
. A for loop is then used to iterate through the different types of bears printing a list item for each type.
- HubL
- Output
Other HubL features
Below are a few other miscellaneous templating features that may be useful, as you develop with HubL.Escaping HubL delimiters
Many other languages share the same delimiters as HubL, which can create issues when working in coded files on the CMS. If you want to use a HubL delimiter for a different language, or otherwise prevent code from being rendered as HubL, you can wrap it with{% raw %}
/ {% endraw %}
.
Including files in files
You can use the{% include %}
tag to include other files in a file. For example, use it to include multiple .html
files in one HubL template, as shown below.
Blocks and extends
When creating complex templates, you can use create compartmentalized blocks that extend a parent template. First, you’ll create a main template that includes the requiredstandard_header_includes
and standard_footer_includes
variables. Within that template, you need to define a unique block using the following syntax where my_sidebar
is a unique name:
Copy section HubL
In the page editor, you can copy the HubL markup for a drag and drop section to reuse the code as needed. This can be helpful when wanting to recreate a drag and drop section in a coded file.