Getting started with modules
In this tutorial, you'll use the HubSpot CMS boilerplate theme to learn how to create a module and walk through how you can use it in templates and pages as part of a theme. By the end of the tutorial, you'll have created a customer testimonial module that includes a text field, an image field, and a rich text field.
Before getting started with this tutorial:
- Set up a HubSpot CMS Developer Sandbox. You can use your existing account instead, but the sandbox will allow you to develop without impacting assets in your main account.
- Install Node.js, which enables HubSpot's local development tools. Versions 10 or higher are supported.
If you want to jump ahead, you can preview the finished project files. Because the CMS boilerplate theme's code may change over time, only the most critical files that developers will need to create or edit during the tutorial are included. These files include:
- Testimonial.module: the folder containing the files that make up the custom module you'll build as part of the tutorial.
- homepage.html: the template that you'll be editing to include the custom module.
- images: the folder containing the profile pictures you'll use in the module.
During this tutorial, you'll be developing the module locally. To interact with HubSpot in your command line interface, you'll need to install the HubSpot CLI and configure it to access your account.
- In the terminal, run the following command to install the CLI globally. To install the CLI only in your current directory instead, run
npm install @hubspot/cli
.
- In the directory where you'll be storing your theme files, authenticate your HubSpot account so that you can interact with it via the CLI.
- Press Enter to open the personal access key page in your browser.
- Select the account that you want to deploy to, then click Continue with this account. You’ll then be redirected to the personal access key page of the account.
- Next to Personal Access Key, click Show to reveal your key. Then click Copy to copy it to your clipboard.
- Paste the copied key into the terminal, then press Enter.
- Enter a unique name for the account. This name will only be seen and used by you when running commands. Then, press Enter.To connect the local development tools to your account:
You'll then see a success message confirming that the hubspot.config.yml
file was created.
- Run the command below to create a new theme named
my-theme
. A theme folder namedmy-theme
will then be created in your working directory containing the boilerplate assets.
- Upload the files to your account.
Parameter | Description |
---|---|
<src>
| The path to your local files, relative to your current working directory. |
<destination>
| The destination path in your HubSpot account. This can be a new folder. |
hs upload my-theme my-new-theme
would upload the my-theme
folder from your machine to a my-new-theme
folder in HubSpotBy default, HubSpot will upload to the default account in your hubspot.config,yml
file. However, you can also specify an account by including a --account=<accountNameOrId>
flag in the command. For example, hs upload --portal=mainProd
.
Learn more in the CLI command reference.
With the CMS boilerplate in your local environment, you'll now create a new module for the theme.
- Log in to your HubSpot account, then navigate to the design manager by navigating to Marketing > Files and Templates > Design Tools.
- In the left sidebar of the design manager, open the theme folder that you just uploaded.
- In the theme folder, open the modules folder.
- In the upper left, click File > New file to create a new module in this folder.
- In the dialog box, click the dropdown menu, then select Module, then click Next.
- Select the Pages checkbox to make the module available for website and landing pages.
- Name the module Testimonial, then click Create.
Next, you'll add three fields to the module:
- A text field to store the name of the customer giving the testimonial.
- An image field that will store the customer's profile picture.
- A rich text field that will store the customer's testimonial.
Add the text field for customer name
- In the right sidebar of the module editor, click the Add field dropdown menu, then select Text.
- In the right sidebar, click the pencil icon in the upper right to name the field. For this tutorial, enter the Customer Name. You'll then see the HubL variable name change to customer_name.
- Set the Default text to Sally.

- In the right sidebar, click the breadcrumb icon to return to the main module menu.
Add the image field for customer profile picture
- Add another field using the same method, this time selecting the Image field type.
- Label the image field Profile Picture, then set the HubL variable name to profile_pic.
- Under Default image, select the profile picture provided for Sally in the images folder of the completed project files.
- Set the Alt text to Sally Profile Picture.

Add the rich text field for Sally's testimony
- Add another field using the same method, this time selecting the Rich text field type.
- Label the rich text field Testimonial.
- Click the Default rich text box, then enter "I've had nothing but wonderful experiences with this company."

So far, you've added data into several module fields. At this point, though, the module doesn't contain any HTML to render that data. In the module editor, this is reflected by the empty state of the module.html
section.
Next, you'll add HubL to module.html
to display the field data.
To display data from the previously created fields, add the following HubL to the module.html
pane:
The above HubL tokens use dot notation to access data from each field. In this case, because we want to pull data from module fields, each token begins with module
, followed by the field's HubL variable name. You can use dot notation to further access specific properties of a field, which you can see in the profile_pic
tokens on line 3 above.
- With the HubL added to your module, click Preview in the upper right to see what the module looks like so far.

- Then, in the upper right, click Publish changes.
Having created and published the module in HubSpot, you'll now use the CLI to pull the module down into your local environment so that you can view its contents and make further changes.
To view the module locally, you'll first need to pull it down to your local theme:
- In the terminal, run the following command:
hs fetch <hs_src> <destination>
:<hs_src>
represents the module's filepath in HubSpot. To get the filepath, you can right-click the module in the left sidebar of the design manager, then select Copy path.<destination>
represents the path to the local directory where your theme lives. If omitted, the command will default to the current working directory.
For example, if you're in the working directory already, your fetch command may look similar to the following:
In your preferred code editor, navigate to the module folder you’ve just pulled down from your HubSpot account. Within your module folder, you will see five different files:
Parameter | Description |
---|---|
fields.json
| A JSON object that contains your module’s fields. |
meta.json
| A JSON object that contains meta information about your module. |
module.css
| The CSS file that styles your module. |
module.html
| The HTML and HubL for your module. |
module.js
| The JavaScript for your module. |
You can find more detailed information in our documentation about the module file structure, especially concerning the fields.json
and meta.json
files. In this tutorial, we’ll focus on the fields.json
, module.css
, and module.html
files and how they are generated by, downloaded from, and uploaded to the module editor in the Design Manager.
Open the module's fields.json
file. Aside from some of the id
numbers, the src
attribute of the image field, and potentially the order of fields, the file should contain a JSON object similar to the following:
The values for the following fields will match the values you added in step 3:
name
: the name of the field.label
: the field's label.default
: the field's default value.
The module.html
file should contain the HubL and HTML that you wrote in the HubL + HTML module editor previously.
To make this code more interesting and ready for CSS styling, copy and paste the following code into the file:
Writing your HTML as above uses the BEM class structure in accordance with the HubSpot CMS boilerplate theme's style guide.
The module.css
file should be empty at this point. To add styling, copy and paste the following code into the file:
After adding the code, save the file.
After saving your local changes, push them back to your HubSpot account.
- Navigate to your terminal and ensure that you're in the correct directory.
- Run the watch command to push changes to HubSpot on save:
hs watch <src> <destination>
.
- In your HubSpot account, navigate to Marketing > Files and Templates > Design Tools.
- In the left sidebar, navigate to the theme you've created, then open the module folder and select the Testimonial module.
- With the module open, you should now see your changes in the
module.html
andmodule.css
panes. - In the upper right, click Preview. A new tab will open to display the module preview.

To recap this tutorial so far, you have:
- created a module in HubSpot.
- pulled that module down to your local environment.
- made changes to the HubL + HTML and CSS using your local development tools.
In the next part of this tutorial, learn how to use the module in a template.
By their most basic definition, modules are editable areas of HubSpot templates and pages. You can insert modules into templates in HubSpot by using the design manager, but here you'll be using HubL to add the module to the template in your local environment.
- In your code editor, open the
templates
folder, then open thehome.html
file. - In the
home.html
file, navigate to the finaldnd_section
, which starts around line 28. You'll be adding your new module to this section. - Within this
dnd_section
and above the otherdnd_modules
, copy and paste the following HubL module tag:
This HubL tag references your new module by its relative file path. To get the module to fit evenly with the other two modules in the dnd_section
, it also assigns a module width
and offset
:
- HubSpot's CMS uses a 12-column grid system, so to space this module evenly with the other two, you'll need to update each module in the
dnd_section
to have a width of4
. - Then, the first
dnd_module
in the group (testimonial
) will have an offset of0
to position it first. - The second
dnd_module
(linked_image
) will have an offset of4
to position it second. - The third
dnd_module
(rich_text
) will have an offset of8
to position it third.
After setting the offset
and width
of each dnd_module
, your code will look similar to the following:
When adding a module to a Drag and Drop area, the module tag does not require a unique name. However, when adding a module to a HTML file outside of Drag and Drop areas, you must assign the module a unique name. You would also use slightly different syntax, such as:
{% module "testimonial_one" path="../modules/Testimonial.module" %}
Learn more about using modules in templates.
- If you haven’t kept the watch command running to track your saved work automatically, run hs watch <src> <dest>. Ensure that this command keeps running as you complete the next steps.
- In your HubSpot account, open the design manager (Marketing > Files and Templates > Design Tools).
- In the left sidebar of the design manager, select the home.html file.
- In the upper right, click Preview, then select Live preview with display options to open the template preview in a new window.

- In the new tab, view the template preview, which should contain your newly added testimonial module.

To make the homepage template more interesting:
- Navigate back to your code editor, then open the
home.html
file. - Add the following parameters to the testimonial module tag:
The above parameters override the default values that you originally assigned to the three fields. Each parameter uses the HubL variable name that you assigned to each field previously:
customer_name
: this parameter passes the nameMary
to the customer name field, overriding the original value ofSally
.profile_pic
: this parameter is an object that contains two properties:- The
src
property uses theget_asset_url
HubL function to retrieve the URL for the new profile picture. Note that the image's file path is relative to your working directory. You'll first need to add this image to theimages
folder in your local theme files. You can find the image in theimages
folder of the completed project files. - The
alt
property assigns the image's alt text.
- The
testimonial
: this parameter passes new text into the testimonial field.
Alternatively, for the rich text field you could use HubL block syntax to write a large block of HTML or text:
Learn more about module block syntax.
If you’ve kept the watch command running in your terminal, saving your changes will send them to HubSpot. You can then navigate back to the design manager to preview the template.
In this step, you'll add two more testimonial modules to the template using the same steps as before:
- Navigate to your code editor, then open the
home.html
file. - Under the testimonial module you previous added, add another instance of the module by copying and pasting that module's code. In the new testimonial module, specify the following details using the same steps as above:
- The customer's name is
Ollie
. - Ollie's testimonial reads:
I can't believe that I ever conducted business without the use of this product!
- For Ollie's picture, add the relative file path for the file within the
images
folder. You can get the image itself from the finished project files. Then give Ollie's image thealt
attribute ofOllie Profile Picture
. - To maintain spacing, set
offset
to4
andwidth
to4
.
- The customer's name is
- Underneath the second testimonial module, add a third with the following details:
- The customer's name is
Erin
. - Erin's testimony reads:
My business has nearly tripled since I began to use this product! Don't wait, start now!
- For Erin's picture, add the relative file path for the file within the
images
folder. Then give Erin's image thealt
attribute ofErin Profile Picture
. - To maintain spacing, set
offset
to8
andwidth
to4
.
- The customer's name is
- Save your changes.
If you’ve kept the watch
command running in your terminal, you can navigate back to the Design Manager to preview your changes to the template. The template preview should now contain all three testimonial modules.

As a final step, you'll prepare the theme for use in a live page by modifying the theme.json
file.
If you'd like to modify the default name of the theme, you can do so by configuring the name
and label
fields in the theme.json
file.
After adding that code, save your changes so that the watch
command sends your changes to HubSpot.
Now that you've created a custom module, added it to the home.html
template, and optionally customized the theme name, you're ready to create a live page from the theme.
If you'd like to follow a similar tutorial that focuses on themes, check out the Getting started with themes tutorial next. Otherwise, you can learn more about creating and customizing pages in HubSpot's Knowledge Base.
Or, if you'd like to learn more about modules, check out the following module guides:
Thank you for your feedback, it means a lot to us.