HubSpot Asset Marketplace module requirements

Last updated:

Below, learn about the requirements that a theme's modules need to meet when submitting a theme to the Asset Marketplace.

Module restrictions

Modules must not contain HubDB, calls to serverless functions, or the CRM object field.

Module screenshots

Modules must contain, at minimum, the following screenshots:

  • How the module will appear on the page to front end users.
  • The page-level editor settings of the module. If repeater content is used in the module, you must provide a screenshot of one instance of the repeating item settings.

Module content

Learn about the requirements for module labels and help text, fields, and default content.

Module labels & help text

  • Modules must have descriptive labels that convey the purpose of the module. The label Hero Banner with Parallax Scrolling is descriptive, whereas the labels Hero Banner and Gallery are not. 
  • Module labels must not contain numbers, such as Hero Banner 01.
  • Module labels must not contain abbreviations, such as Col instead of Column.
  • Modules must contain inline help text where applicable to further convey how to use the module.
  • Module should not be named the same as a default module.

Default content

  • Default field cannot include Lorem ipsum text. 
  • Default field content should represent the field’s purpose:
    • When including menu fields, modules must use Select a menu as the default content option.
    • When including form fields, modules must use Select a form as the default content option.
    • When including blog selector fields, modules must use Select a blog as the default content option.
  • If adding default content to a module doesn't make sense, use a module placeholder instead to help the content creator visualize the space that they'll fill with content.

Module icons

Modules must include a custom icon assigned to the module (replacing the default icon). Do not use company logos as icons, such as Apple or Amazon logos. Learn more about module icons.

Module compatibility with themes

The alternate_names attribute can be used to achieve module compatibility with themes in the Asset Marketplace. It provides the bridge for a module to integrate with as many marketplace themes as possible without much effort from providers and module developers.

Theme providers define a new attribute called alternate_names which contains standard fields mapped to the module fields. Alternate names are supported for fonts and color fields. Module fields will inherit from the standard color and font fields. This is a new attribute introduced for theme fields. For example:

{ "label": "ButtonColor", "name": "button_color", "type": "color", "visibility": { "hidden_subfields": { "opacity": true } }, "alternate_names" : ["primary_color"], "default": { "color": "#516747" } }

In the above example, developers get the ability to access the button color in two ways: theme.button_color and theme.primary_color. This way, providers can update their existing theme to meet asset standards.

Modules and themes must adhere to the following requirements to ensure functionality when used across themes:
  • The font and color style fields must follow these standard naming conventions: primary_color, secondary_color, heading_font, and body_font.
  • If theme fields do not have primary_color, secondary_color, heading_font, or  body_font fields, they can use the alternate_names attribute to map existing fields to standard fields. This way, when an independent module is added to the theme template, it has similar look and feel of themed module.
  • A user can inherit either by defining default_value_path or property_value_paths, or both. Review the code snippet below for an example: 
    • If you use default_value_path, the accepted value is theme.primary_color.
    • If you use property_value_paths you must use trailing individual properties .color or .opacity based on the property they are mapping. 
[ { "id" : "d506e41f-7206-bb8f-7fa5-d4a7de75c61e", "name" : "color", "display_width" : null, "label" : "Color", "required" : false, "locked" : false, "type" : "color", "inherited_value": { "default_value_path": "theme.primary_color", "property_value_paths": { "color": "theme.primary_color.color", "opacity": "theme.primary_color.opacity" } }, "default" : { "color" : "#00FF03", "opacity" : 100 } } ]
  • In the module.html, these fields can be referred to with the following dot notation:
{{ theme.primary_color }} <br> {{ theme.primary_color.color }} <br> {{ theme.primary_color.css }}
  • When creating a theme, the same standard naming conventions (primary_color, secondary_color, heading_font, and body_font) must be used so that the module fields can be mapped with the standard field names. Developers can either create new module fields that meet the standard naming convention, or use the alternate_names parameter to map existing fields to the standard fields. 
  • The color field with an alternate_name can be accessed directly using theme.primary_color or indirectly using theme.colors.primary. Below is an example: 
{ "label": "Colors", "name": "colors", "type": "group", "children": [ { "label": "Primary", "name": "primary", "type": "color", "visibility": { "hidden_subfields": { "opacity": true } }, "alternate_names" : ["primary_color"] "default": { "color": "#516747" } }] }
  • The font field with an alternate_name can be accessed directly using theme.heading_font or indirectly using theme.fonts.primary.  Review the snippet below for an example: 
{ "label": "Fonts", "name": "fonts", "type": "group", "children": [ { "label": "Primary", "name": "primary", "type": "font", "visibility": { "hidden_subfields": { "bold": true, "italic": true, "size": true, "underline": true } }, "default": { "color": "#231f20", "fallback": "sans-serif", "font": "Montserrat", "font_set": "GOOGLE", "variant": "400" }, "alternate_names":["heading_font"] }

Module code quality

The following requirements must also be met in conjunction with our initial requirements about code quality in our HubSpot Asset Marketplace Compliance, Design, Code Quality, and Disclaimers section. The following requirements are specific to modules.

Modules must be self-contained

All module code must be self-contained and not rely on code located elsewhere. External files utilized inside of modules must use the Linked Files feature.

Styles and JavaScript

  • Styles:
    • Modules must have a non-empty style group.
    • Hardcoding inline styles within modules is not recommended. Instead, use dynamic inline styles by enabling fields to control styling.
  • Javascript:
    • All JavaScript must be able to represent multiple instances of a module. JavaScript in the JS Pane will only load once per page, regardless of the number of module occurrences.
    • JavaScript should reference DOM elements by module specific classnames to ensure elements outside of the module are not unintentionally affected. 

When creating modules, you can use a built-in variable called {{name}}. This variable pulls in the module's instance ID (which can be used in the HTML+HubL panel only) to help in CSS and JS markup for complex modules. Learn more about this in our developer documentation.

Field organization

The following field organization and grouping requirements must be met.

Content tab

  • Where there is at least one control within a field group, all controls must be grouped into categories labeled by their function.
  • Module fields added to the Content tab must provide ways to customize the content of a module. For example, controls for font size, image, icon, alt-text, and link controls.

Styles tab

Module style field groups must be consistent and follow a pattern. Below is a recommended order for your style field groups. These groups can either be at the top level or nested one group deep. Empty groups may also be removed:
  • Presets
  • Text
  • Background
  • Border
  • Hover
  • Corner
  • Spacing
  • Alignment
  • Custom style groups that don't fit the above
  • Advanced

The following field types must be contained in the Styles tab if present:

When moving fields from the Content tab to the Styles tab, learn how to use alias mapping to preserve styling for modules that are already in use on live pages.
  • Animation options should always be positioned near the bottom of the field group list.
  • Options that allow content creators to add code snippets or CSS should be grouped at the end of the field group list under a field labeled Advanced
  • Controls should be standardized across all modules. For example, all elements that can have a border radius control should offer that control. Avoid offering controls on some modules that are absent on others.
  • Module fields added to the Style tab must provide ways to style the module. For example:
    • Style options such as color, text styling, alignment, spacing, border, and corner radius.
    • Animations such as hover and slide-in effects.
    • Presets such as dark and light themes that are meant to change many styles at the same time.

Examples of field organization


Presets can be used when wanting to give content creators a limited set of options, often tying back to theme settings. For example, the Icon module included in the Growth theme contains presents for Dark and Light colors, which enables consistency when used across the website. 

Multi-level grouping

When deciding whether to keep style fields at the top level or nest them, consider the following example.

The Icon module included in the Growth theme lists all its styles at the top level because it's one component, and therefore its style options all impact the one component. 


The Speaker card module included in the Growth theme contains multiple components: the card's image and its text contents. Module styles are therefore grouped by component so that the content creator has a more clear process for styling each component.


Grouping individual fields

The button module below contains groupings for Presets, Text, Background, and more. Although the Corner field group contains only the corner radius control, it’s still grouped to create a uniform content creation experience.




Alias mapping enables you to create field mappings in a module so that you can move, rename, or replace its fields without impacting pages that are using the module. 

For example, a module is being used on a live page. You want to move some fields into the Styles tab, such as color or font, but a content creator has already selected values for those fields in the editor. If you were to move those fields without setting up alias mapping, HubSpot would not be able to relocate those fields and they would revert to their default values, which would undo the styling on the live page.

Instead, you can add an aliases_mapping property to a field to map it to another one. Then, when a value has not been set for the original field, HubSpot will check if a value exists in the mapped field. If no value exists in the mapped field either, it will use the default value instead. This property can be used to map field values between different versions of a module only when the stored data type of the old field is the same as the new field's stored data type.

For a visual walkthrough of this feature, check out video below.

To migrate existing fields to aliases:

  1. Create new fields and map them to old fields using the aliases_mapping property.
  2. Remove the old field definition.
  3. Update the module.html file to use the new fields definition.

Please note:

  • You cannot map fields that are of a different data type to each other. For example, you can't map a background gradient field to an image field. The stored value has to be a valid value for the new field's type.
  • When creating a new field with an alias mapping to an old field, the default values and required properties of both fields should be the same.

Below are examples of implementing this for both simple and complex changes:

Simple implementation

In simple situations, the field type of the old field and the field type of the new field should be the same. For example:

  • Old color field to new color field. 
  • Old text field to new text field.
  • Old spacing field to new spacing field.

Below is an example of using aliases_mapping when moving a color field from the module's Content tab to the Styles tab.

Example of a v0 module

[ { "label": "Button Color", "name": "old_button_color_field", "type": "color", "required": true, "default": { "color": "#FFFFFF", "opacity": 100 } } ]

Example of a v1 module

[ { "label": "Styles", "name": "styles", "type": "group", "tab": "STYLE", "children": [ { "label": "Button Color", "name": "new_button_color_field", "type": "color", "required": true, "aliases_mapping": { "property_aliases_paths": { "new_button_color_field": ["old_button_color_field"] } }, "default": { "color": "#FFFFFF", "opacity": 100 } } ] } ]

Complex implementation

In more complex situations, you can also map fields to subfields or other module field types as long as the data type is the same, and the new field's subfield type matches. Subfields are the properties within the field's stored value object. For example:

  • Mapping a Rich text field to a Text field, as the values in both fields are stored as strings.
  • Consolidating typography fields, such as changing from a number field for font size, to use a font field (which has a font size sub field). You can add an alias for the size subfield to map it to the old number field by using dot notation.

Below is an example of changing the font sizing option from a number field to a font field which has a font size sub field.

Example of a v0 module

[ { "name": "my_number_field", "label": "Number field", "required": false, "locked": false, "display": "text", "step": 1, "type": "number", "min": null, "max": null, "inline_help_text": "", "help_text": "", "default": null } ]

Example of a v1 module

[ { "name": "my_font_field", "label": "font_field", "required": false, "locked": false, "inline_help_text": "", "help_text": "", "load_external_fonts": true, "type": "font", "aliases_mapping": { "property_aliases_paths": { "my_font_field.size": ["my_number_field"] } }, "default": { "size": 12, "font": "Merriweather", "font_set": "GOOGLE", "size_unit": "px", "color": "#000", "styles": {} } } ]

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