Using Modules in Templates

Last updated:

Modules can either be added directly to a template or added to individual pages with drag and drop areas and flexible columns. When a module is added to a template, the module will appear in that location by default. Modules in drag and drop areas and flexible columns can be moved and removed, and other modules can be added around them. These are module instances.

After a module has been defined, you can get its field values at the template level through the content.widgets dict.

Basic module syntax

HubL module tags are delimited by {% %} , and must specify module, a unique name, and the module's design manager path. A module can also include parameters for additional settings.

  • Module name: gives the module a unique identity in the context of the template. 
    • The name must be in quotes following the type of module, and must use underscores instead of spaces or dashes.
    • This name is used to match the content set within the page/email editor with the corresponding HubL module tag. For example, if you code a HubL module tag with the same name in two different areas of a template, users will only have one module to edit in the editor, but changes to that module will apply in both locations. 
  • Path: depending on the tag, defines the location of where the module is in the design manager.
    • / means the root of the current drive;
    • ./ means the current directory;
    • ../ means the parent of the current directory.
The path for HubSpot default modules always start with @hubspot/ followed by the type of module.
  • Parameters: additional settings for the module instance, specifying its behavior and how it renders. Includes template-level default values for module fields.
    • Parameters are comma-separated key-value pairs.
    • Parameters have different types, including: string, boolean, integer, enumeration, and JSON list object. String parameters values must be in single or double quotes, while boolean parameters do not require quotes around their True or False values. Learn more about the parameters that are available for all modules.
    • Note that there is no in-editor validation for field values compared to the module's field settings. For example, if module has a number field that has a minimum value set to 1, and you pass into the parameter a 0, you will not see a warning that the value is invalid.
{# Basic syntax #} {% module "unique_module_name" path="@hubspot/module_type", parameterString='String parameter value', parameterBoolean=True %} {# Sample of a default HubSpot text module #} {% module "job_title" path="@hubspot/text", label="Job Title", value="Chief Morale Officer" %} {# Sample of a custom module #} {% module "faqs" path="/myWebsite/modules/faq_module", label="Custom FAQ Module" faq_group_title="Commonly Asked Questions" %}

Passing dicts to module parameters

For modules with fields that expect dicts, you can pass them like you would other parameters. If it's cleaner to you or you plan to re-use the values, you can set the dict to a variable, and pass the variable to the parameter instead.

{% module "social_buttons", path="@hubspot/social_sharing", email={ "default": true, "enabled": false, "img_src": "https://..." } %}

Passing fields that have dnd associated parameters

Drag and drop tags, such as dnd_area, come with a set of default parameters, such as width. While the design manager will prevent you from creating new fields that use one of these reserved parameters, modules created before drag and drop tags were introduced may already use a reserved parameter. 

To fix this, you can use the fields parameter. Just like you would pass field data to a group, you can pass the field name as a key on the fields object. Its value must be consistent with the format the field type expects.

{% dnd_area "main_content"%} {% dnd_section %} {% dnd_column %} {% dnd_row %} {% dnd_module path="@hubspot/divider", fields={width: "90"} %} {% end_dnd_module %} {% end_dnd_row %} {%end_dnd_column%} {% end_dnd_section %} {% end_dnd_area %}

Setting template-level default values for fields

You can set default values for module fields at the template level by including parameters in the dnd_module tags. Below, learn how to set default field values in nested field groups, repeating fields, repeating field groups, and style fields.

Setting default values for nested field groups

Below is an example of a custom drag and drop module with a custom  style field group containing other nested field groups. Compare its template-level configuration with how this same grouping would appear in the design manager.

{% dnd_module path="/Nested_Module.module" style={ "group":{ "section":{ "color_field":{ "color" : "#000", "opacity" : 100 } } } } %} {% end_dnd_module %}
multi-level field nesting

Setting default values for repeating fields

You can set template level default values for repeating fields by passing an array to the field's parameter. The array's items must be in the format expected based on the field type. For example:

  • A simple text field only expects a string
  • An image repeater field expects an image field object. This applies to all of the other field types.
{% module path='../modules/recipe_card.module', ingredients=["Eggs","Ham","Cheese"] %} {% module "my_repeater_module" path="/img_repeater_module", label="img_repeater_module", image=[ { "src" : "", "alt" : "HubSpot Developers", "width" : 254, "height" : 31 },{ "src" : "", "alt" : "Dharmesh", "width" : 394, "height" : 394 } ] %}

Setting default values for repeating field groups

Modules that contain repeating groups of fields - like you might see in a slideshow module or FAQ module - can have a template level default set for those groups. To do this you pass an array of objects to your field group's parameter.  The key and value pairs of the object are the field names and their values.

{% module path='../modules/slideshow.module', slides=[ { "caption":"Cute dog looking up", "image_url":"", }, { "caption":"Cuter cat not looking amused", "image_url":"", } ] %}

Setting default values for style fields

you can explicitly set default values for style fields using the styles parameter.

This works just like other groups do, where the parameter is the name of the group. You pass an object to that parameter with all of the fields you wish to set.

{% dnd_module path="./path/to/module", styles={ "background_color":{ "color":"#123", "opacity":50 } } %}

Block Syntax

While most modules have parameters that control default content, there may be situations where you need to add large code blocks to the default content of a module. For example, you may want to include a large block of HTML as the default content for a rich text or HTML module. Rather than trying to write that code into a value parameter, you can use HubL block syntax.

{% module_block module "my_rich_text_module" path="/My Rich Text Field Module", label="My Rich Text Field Module" %} {% module_attribute "rich_text_field_variable" %} <div>My HTML block</div> {% end_module_attribute %} {% end_module_block %}

Prior to the module_block syntax, widget_block was used. It follows the same pattern but the opening tags were widget_block, and widget_attribute. Closing tags were end_widget_attribute, end_widget_block.

The widget_block syntax is deprecated but you don't need to update old code.

The parameter that immediately follows module_block or widget_block(deprecated) is the type_of_module parameter.

In nearly all of our documentation you will find we use module. V2 HubSpot Modules are normal modules, like what you can create. Therefore there's no longer a need to use a different type_of_module.

While widget_block is deprecated, and you should use module_block. If inheriting a website from another developer it may contain old code using widget_block and type_of_module.

The type_of_module supports V1 HubSpot module names for example: rich_text or raw_html. Additional parameters can be added to the first line of HubL. The second line defines which parameter the contents of the block will be applied to. For example, for a rich_text module this should be the html parameter. For a raw_html module, this would be the value parameter (see both examples below). 

{# widget_block is deprecated, use module_block instead. This example is only to explain what type_of_module was used for, for those with legacy code. #} {% widget_block rich_text "my_rich_text_module" overrideable=True, label='My rich-text module' %} {% widget_attribute "html" %} <h2>New Module</h2> <p>Add content here.</p> {% end_widget_attribute %} {% end_widget_block %}<span id="hs_cos_wrapper_my_rich_text_module" class="hs_cos_wrapper hs_cos_wrapper_widget hs_cos_wrapper_type_rich_text" style="" data-hs-cos-general-type="widget" data-hs-cos-type="rich_text"> <h2>New Module</h2> <p>Add content here.</p> </span>


In addition to regular and block syntax, there are certain instances where you may want to specify a large block default content for a predefined content variable. The most common example of this proves to be the content.email_body variable. This variable prints a standard email body that can be altered in the content editor. Since this isn't a standard HubL module, we use a content_attribute tag to specify a block of default content. The example below shows the email body variable populated with a default content code block.

{% content_attribute "email_body" %} <p>Hi {{ contact.firstname }},</p> <p>Describe what you have to offer the customer. Why should they read? What did you promise them in the subject line? Tell them something cool. Make them laugh. Make them cry. Well, maybe don't do that...</p> <p>Use a list to:</p> <ul> <li>Explain the value of your offer</li> <li>Remind the reader what they’ll get out of taking action</li> <li>Show off your skill with bullet points</li> <li>Make your content easy to scan</li> </ul> <p><a href="">LINK TO A LANDING PAGE ON YOUR SITE</a> (This is the really important part.)</p> <p>Now wrap it all up with a pithy little reminder of how much you love them.</p> <p>Aw. You silver-tongued devil, you.</p> <p>Sincerely,</p> <p>Your name</p> {% end_content_attribute %}

Parameters available for all modules

While some modules have certain special parameters, below is a list of parameters supported by all modules.

ParameterTypeDescription Default

The name of the module displayed in the content editor. This parameter can also be used to give users additional instructions.


Controls whether or not the module can be edited in the content editor, equivalent to the Prevent editing in content editors setting in the design manager.


When set to True, removes the wrapping markup from around the content of a module.

On pages, modules are always wrapped in a <div> with special classes. This wrapping markup makes it so when you click the module in the preview pane, the editor scrolls to that module. There may be instances where you want to remove the wrapper, such as if you want to use a text module to populate the destination of an anchor tag href attribute.


Adds classes to the module wrapper. You can add multiple classes by separating the classes with spaces. For example:

extra_classes='full-width panel'


When set to True, instead of rendering the HTML, the parameters from this widget will be available in the template context. Learn how to use this parameter and the widget_data tag.


When the module is defined within a loop, appends the module name with the loop.index. When set to True, a different version of the module will print within each iteration of the loop. Appends the module name with the loop.index.


To see a complete list of all module types and their parameters, click here.

Field-based parameters

Below, learn about the field-based module parameters you can use.

Field Type Example Keys
Blog Integer (blog ID) 1234567890  
Boolean True/false false  
Choice String "option_1"  
Color Object
  "color" : "#ffffff",
  "opacity" : 100
6 character hexidecimal format
integer 0 - 100
CTA String (CTA ID)
Date Timestamp
Datetime Timestamp
Email address Array (email address strings)
["", ""]
File String (URL of file)
Follow Up Email Integer (follow up email ID)
Font Object
  "size" : 12,
  "size_unit" : "px",
  "color" : "#000",
  "styles" :{
    "text-decoration" : "underline"
  "font" : "Alegreya",
  "fallback" : "serif",
  "variant" : "regular",
  "font_set" : "GOOGLE"
font size without unit type
font size unit string
  • "px"
  • "pt"
  • "em"
  • "rem"
  • "%"
  • "ex"
  • "ch"
hex color code string
supported properties
"normal" / "bold"
"normal" / "italic"
"none" / "underline"
Form Object
  "form_id" : "9aa2e5f3-a46d-4774-897e-0bc37478521c",
  "response_type" : "redirect",
  "redirect_url" : "",
  "redirect_id" : null,
  "form_type" : "HUBSPOT"
The form's ID. How to get a form's id.
"redirect" / "inline"
Message displayed if using response_type "inline". String supporting html.
String, absolute URL to a webpage
Page/Post id to redirect to
HubDB Table Integer (HubDB table ID) 123456789  
Icon Object
  "name" : "align-center",
  "unicode" : "f037",
  "type" : "SOLID"
The icon's name
The unicode symbol for the font the icon is from
Symbol style. "SOLID" / "REGULAR"
It is recommended you set an icon field and view the values that way, to set the parameters properly.
Image Object
  "src" : "",
  "alt" : "an_image",
  "width" : 100,
  "height" : 100
Image URL
Image alt text, used by screen readers and search engines
The width at which the image is to be displayed
The height at which the image is to be displayed
Meeting String (meeting link) ""  
Menu Integer (menu ID) 123456789  
Number Integer 1  
Page Integer (page ID) 1234567890  
richtext String (can contain HTML) "<h1>Hello, world!</h1>"  
Salesforce Campaign String  (Salesforce campaign ID) "7016A0000005S0tQAE"  
Simple Menu Array of menu item objects
    "isPublished" : true,
    "pageLinkId" : 123456789,
    "pageLinkName" : "My page",
    "isDeleted" : false,
    "categoryId" : 1,
    "subCategory" : "site_page",
    "contentType" : "site_page",
    "linkLabel" : "This is a page",
    "linkUrl" : null,
    "linkParams" : null,
    "linkTarget" : null,
    "type" : "PAGE_LINK",
    "children" : [ ]
true/false is the menu item's page published?
Page id in the CMS
The page's actual name in the CMS
  • 1 - Site Page
  • 3 - Blog post
  • site_page
  • landing_page
  • blog
  • normal_blog_post
  • site_page
  • landing_page
  • blog
text the user reads and clicks
actual URL the user is sent to upon clicking
# links or ? query parameters
if open in new tab is enabled "_blank" otherwise "null"
  • "NO_LINK"
array of menu item objects, identical to individual menu items.
Tag Integer (tag ID or slug, ID is recommended) 1234567890  
Text String "it's like any other string"  
URL Object
  "type" : "CONTENT",
  "href" : null,
  "content_id" : 123456789
  • "EXTERNAL" for non HubSpot non-email URLs
  • "CONTENT" for pages, blog posts, and landing pages
  • "FILE" for files uploaded to the file manager
  • "EMAIL_ADDRESS" for email addresses
  • "BLOG" for blog listing pages
String, the URL you are linking to.

Was this article helpful?
This form is used for documentation feedback only. Learn how to get help with HubSpot.