Displaying HubDB Data
This article explains how to display data synced from spreadsheets to HubDB on your HubSpot websites and blogs.
We use custom modules for display. Create them in Design Manager and use HubL (HubSpot's template language) to fetch and display data from HubDB.
Creating a Module
1. Open Design Manager
HubSpot Dashboard → Marketing → Files and Templates → Design Manager
2. Create New Module
- "File" → "New File" → "Module"
- Enter module name (e.g.,
HubDB Product List) - Click "Create"
3. Add Fields
Add a field in the module settings to input the HubDB table ID.
- Click "Add field" on the right panel
- Select "Text"
- Field name:
hubdb_table_id - Label:
HubDB Table ID - Enter a default table ID
Why Make Table ID a Field?
Making the table ID a field allows you to reuse the same module with different HubDB tables. You can switch displayed data per blog or landing page.
HubL Code Implementation
Basic Data Retrieval and Display
Write the following code in module.html:
{% set tableid = module.hubdb_table_id %}
{% set rows = hubdb_table_rows(tableid) %}
<div class="product-list">
{% for row in rows %}
<div class="product-item">
<h3>{{ row.hs_name }}</h3>
<p>{{ row.description }}</p>
</div>
{% endfor %}
</div>
Pagination Display
For large datasets, add pagination:
{% set tableid = module.hubdb_table_id %}
{% set table_info = hubdb_table(tableid) %}
{# Items per page #}
{% set batch_num = 12 %}
{# Get current page number #}
{% if not request.query_dict.page_num %}
{% set page_num = 1 %}
{% set offset_num = 0 %}
{% elif request.query_dict.page_num %}
{% set page_num = request.query_dict.page_num %}
{% set offset_num = page_num|add(-1) * batch_num %}
{% endif %}
{# Build query and fetch data #}
{% set query = "limit=" ~ batch_num ~ "&offset=" ~ offset_num %}
{% set rows = hubdb_table_rows(tableid, query) %}
{# Data display section #}
<div class="products" id="list">
{% for row in rows %}
<div class="product-item">
<div class="product-image">
<img src="{{ row.image_url }}" alt="{{ row.hs_name }}">
</div>
<div class="product-info">
<h4>{{ row.hs_name }}</h4>
{% if row.description %}
<p>{{ row.description }}</p>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{# Pagination #}
{% set nav = hubdb_table_rows(tableid) %}
{% set total_pages = nav|length|divide(batch_num) %}
<div class="pagination">
{% if page_num > 1 %}
<a href="{{ content.absolute_url }}?page_num={{ page_num|add(-1) }}#list">
Previous
</a>
{% endif %}
<span>{{ page_num }} / {{ total_pages|round(0, 'ceil') }}</span>
{% if total_pages > page_num %}
<a href="{{ content.absolute_url }}?page_num={{ page_num|add(1) }}#list">
Next
</a>
{% endif %}
</div>
Ranking Display Example
Example displaying data with rank numbers:
{% set tableid = module.hubdb_table_id %}
{% set rows = hubdb_table_rows(tableid, "orderBy=order_num") %}
<div class="ranking-header">
<p>Popular Rankings</p>
</div>
<div class="ranking-list">
{% for row in rows %}
<div class="ranking-item" id="item-{{ row.product_code }}">
<div class="rank-badge">
<span>{{ row.order_num }}</span>
</div>
<div class="item-image">
<img src="{{ row.image_url }}" alt="{{ row.hs_name }}">
</div>
<div class="item-title">
<h4>{{ row.hs_name }}</h4>
</div>
<div class="item-detail">
{% if row.item_detail %}
<p>{{ row.item_detail }}</p>
{% else %}
<p>See product page for details.</p>
{% endif %}
</div>
<div class="item-link">
<a href="{{ row.product_url }}" target="_blank">View Details</a>
</div>
</div>
{% endfor %}
</div>
CSS Style Examples
Example styles for module.css:
Grid Layout
.products {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.product-item {
position: relative;
padding: 20px;
display: flex;
flex-direction: column;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.product-item img {
max-width: 100%;
width: 100%;
}
.product-info h4 {
font-size: 16px;
line-height: 1.2;
margin-bottom: 10px;
}
/* Mobile responsive */
@media (max-width: 767px) {
.products {
grid-template-columns: repeat(2, 1fr);
}
.product-item {
padding: 10px;
}
}
Ranking Styles
.rank-badge {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 40px;
background-color: #f4f4f4;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
font-weight: bold;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.item-link a {
display: inline-block;
padding: 10px 20px;
background-color: #000;
color: #fff;
text-decoration: none;
transition: background-color 0.3s;
}
.item-link a:hover {
background-color: #333;
}
Pagination Styles
.pagination {
display: flex;
justify-content: center;
align-items: center;
gap: 15px;
margin-top: 30px;
}
.pagination a {
padding: 10px 20px;
background-color: #f0f0f0;
color: #333;
text-decoration: none;
border-radius: 5px;
transition: background-color 0.3s;
}
.pagination a:hover {
background-color: #333;
color: #fff;
}
Using the Module
Insert into Blog Posts
- Open blog post editor
- Click "Add module"
- Select your HubDB module
- Enter HubDB table ID
- Publish
Place on Landing Pages
- Edit template in Design Manager
- Drag and drop module into place
- Configure table ID in module settings
HubL Function Reference
Key HubL functions for HubDB:
| Function | Purpose | Example |
|---|---|---|
| hubdb_table(id) | Get table info | {% set info = hubdb_table(123) %} |
| hubdb_table_rows(id) | Get all rows | {% set rows = hubdb_table_rows(123) %} |
| hubdb_table_rows(id, query) | Get with query | {% set rows = hubdb_table_rows(123, "limit=10") %} |
| hubdb_table_row(table_id, row_id) | Get specific row | {% set row = hubdb_table_row(123, 456) %} |
Common Query Parameters
| Parameter | Description | Example |
|---|---|---|
| limit | Max rows to fetch | limit=10 |
| offset | Rows to skip | offset=20 |
| orderBy | Sort order | orderBy=order_num |
| orderBy (DESC) | Descending sort | orderBy=created_at&order=DESC |
Using Conditionals
HubL conditionals enable data-dependent display:
{% if row.special_flag %}
<span class="badge">Featured</span>
{% endif %}
{% if row.stock_status == 'in_stock' %}
<span class="stock in">In Stock</span>
{% elif row.stock_status == 'low' %}
<span class="stock low">Low Stock</span>
{% else %}
<span class="stock out">Out of Stock</span>
{% endif %}
Summary
Key points for displaying HubDB with HubL modules:
- Table ID as field: Improves reusability
- Pagination: Split large datasets for display
- Responsive design: Consider mobile display
- Conditionals: Dynamic display based on data
Display spreadsheet-synced data with custom designs on your website.