Hi @Strandtc,
welcome to HubSpot!
You’re looking for a socalled “global” module. They are designed exactly the way you want. Set the content once and use it as often as you want/need. The benefit - if you change the content it will be automatically updated on every instance of the module.
Since you’re new to HubSpot development I assume you’re working with the design-tools(which is great to get startet) and haven’t switched to local development/CLI.
To create a global module follow those simple steps:
- Right click on the folder you’d like to create the module in
- Select “Create new file”
- Select “module” in the dropdown
- Select the page-types(pages, blog post, blog listing…; you can change this later) you’d like to use the module in
- Important: Select “global module” instead of “local module” (unless you’re using local environment/CLI you can’t change this setting later)
- Enter a name. You can anything but it should be descriptive and I recommend to use underscores instead of spaces if you enter several words(you can set a label for the page editor later if you want)
- done! - You’ve created a global module

Now it’s about the function itself. Since you’d like to have a slider you’ll need some sort of JS library(at least I recommend to use one). Those are great ones
(Of course you can use any other slider script you want) - the idea/procedure is always the same
Once you’ve decided which library you’d like to use you can:
- implement it right into the module
- create a seperate JS(and CSS) file(s) in your theme/folder structure, paste the needed JS/CSS parts into the right file and link this file inside the module (a few more clicks but can be benifitial for page performance)
If you decide to implement it right into the module write it like this in the HTML + Hubl area
{% require_head %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.js"></script>
{% end_require_head %}
There are several alternatives how to write this since you shouldn’t overload the head with bunch of files but let’s keep this for this example
The next step is quite simple:
Just add all of your desired features into the “Fields” in the right sidebar.
Use an image field for images(you could also use a text field if you want to load images from an external source), for different texts I recommend to use multiple simple text fields instead of one rich-text but it’s up to you
Once you’ve created all of your fields it should look like this:
Now the most important part:
- Click on “Actions” and select “Group”. Select all the fields that should be available for every image (I assume all of those 3) and click “Create group”
- Give this group a name - something like “Images”. Something that is descriptive
- Last but not least - The magic trick: Scroll down to the “Repeater options” of this group, enable thm and - optionally - set a min, max and default number of images you’d like to use
Now this group is a repeater and can be coded with a socalled for-loop.
You’re almost done with the global slider 
Now you have to write the actual layout
Since I’m using swiper.js and the basic layout of it looks like this
<div class="swiper">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
...
</div>
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- If we need scrollbar -->
<div class="swiper-scrollbar"></div>
</div>
I’m placing this exact code right below the already written code into the HTML+Hubl area.
It should look like this now
{% require_head %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.js"></script>
{% end_require_head %}
<div class="swiper">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
...
</div>
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- If we need scrollbar -->
<div class="swiper-scrollbar"></div>
</div>
If you want pagination, prev/next buttons or a scrollbar check out the demos of the slider how to implement those features. I won’t use them for this specific case so my code looks like this now
...
<div class="swiper">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
</div>
And since we’re in HubSpot and we’re using a repeater/for-loop we can modify the code much more so it looks like this
...
<div class="swiper">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
</div>
</div>
Now the fun part - writing the repeater
First: Wrap the single slide div in a for loop so the code looks like this
<div class="swiper">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
{% for single_slide in module.images %}
<div class="swiper-slide">Slide 1</div>
{% endfor %}
</div>
</div>
by doing so everything that is inside the {% for %} and {% endfor %} variable will be created for each item you’ll add to the repeater
Let’s add all created fields to this code so it’ll be actually an image slider.
The whole code should look like this now:
{% require_head %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.js"></script>
{% end_require_head %}
<div class="swiper">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
{% for single_slide in module.images %}
{% set loadingAttr = slingle_slide.image.loading != 'disabled' ? 'loading="{{ slingle_slide.image.loading }}"' : '' %}
{% set href = slingle_slide.link.url.href %}
{% if slingle_slide.link.url.type is equalto "EMAIL_ADDRESS" %}
{% set href = "mailto:" + href %}
{% endif %}
<div class="swiper-slide">
<a href="{{ href }}" {% if slingle_slide.link.open_in_new_tab %}target="_blank"{% endif %} {% if slingle_slide.link.rel %}rel="{{ slingle_slide.link.rel }}"{% endif %}>
<img src="{{ slingle_slide.image.src }}" alt="{{ slingle_slide.image.alt }}" {{ loadingAttr }} class="slider-image">
</a>
<div class="description-wrapper">
<p>
{{ single_slide.description }}
</p>
</div>
</div>
{% endfor %}
</div>
</div>
Let’s add the required JS part so the swiper works
{% require_head %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.js"></script>
{% end_require_head %}
<div class="swiper">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
{% for single_slide in module.images %}
{% set loadingAttr = slingle_slide.image.loading != 'disabled' ? 'loading="{{ slingle_slide.image.loading }}"' : '' %}
{% set href = slingle_slide.link.url.href %}
{% if slingle_slide.link.url.type is equalto "EMAIL_ADDRESS" %}
{% set href = "mailto:" + href %}
{% endif %}
<div class="swiper-slide">
<a href="{{ href }}" {% if slingle_slide.link.open_in_new_tab %}target="_blank"{% endif %} {% if slingle_slide.link.rel %}rel="{{ slingle_slide.link.rel }}"{% endif %}>
<img src="{{ slingle_slide.image.src }}" alt="{{ slingle_slide.image.alt }}" {{ loadingAttr }} class="slider-image">
</a>
<div class="description-wrapper">
<p>
{{ single_slide.description }}
</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% require_js %}
{# this will load the script above the closing body-tag #}
<script>
var swiper = new Swiper(".mySwiper", {});
</script>
{% end_require_js %}
You’re done!
To put content into the module simply click on the “edit global module” button, place your content, save it and use it.
best,
Anton