HubSpot’s HubL (HubSpot Markup Language) is a versatile templating language that powers both HubSpot CMS and HubSpot Email templates. Yet many teams blur the lines between the two. A common pitfall is trying to use CMS features inside emails or expecting the same level of personalization on web pages that you get in emails.
This guide highlights the key differences, shows side-by-side examples, and offers practical takeaways so you can create better-performing pages and campaigns.
Understanding HubL in HubSpot CMS
In the CMS environment, HubL is optimized for scale and structured content delivery. It’s the backbone of HubSpot-hosted websites, landing pages, and blogs, giving developers the flexibility to build dynamic, modular systems.
Key capabilities include:
- Fetching and rendering dynamic content from HubDB tables
- Looping through data with for and while
- Including partials and modules for reusable design blocks
Example: HubL in CMS
<!-- hubdb-loop.html -->
{% set rows = hubdb_table_rows(12345) %}
<ul>
{% for row in rows %}
<li>{{ row.name }} - {{ row.price }}</li>
{% endfor %}
</ul>
{% include “@hubspot/footer” %}
Why it works:
- hubdb_table_rows loads data dynamically.
- The loop iterates through rows, making large datasets manageable.
- The partial (@hubspot/footer) ensures consistent branding.
Understanding HubL in HubSpot Email
HubL for emails is streamlined to focus on personalization. While you don’t get the full CMS toolset, you gain the ability to customize messaging at a granular level, speaking directly to each contact.
Key capabilities include:
- Injecting contact data with tokens ({{ contact.firstname }})
- Using if/else logic to tailor messages
- Creating programmable emails with repeaters and advanced personalization (Enterprise)
Example: HubL in Email
<!-- personalized-email.html -->
<p>Hello {{ contact.firstname|default(“there”) }},</p>
{% if contact.lifecyclestage == “customer” %}
<p>We appreciate your loyalty! Check out our exclusive offers.</p> {% else %}
<p>Explore our products and find your perfect fit.</p> {% endif %}
{% if personalization_token(“contact.favorite_product”) %}
<p>Your favorite product: {{ personalization_token(“contact.favorite_product”) }}</p> {% endif %}
Why it works:
- Personalization tokens fetch real-time contact data.
- Conditional blocks create tailored experiences without duplicating templates.
- Default values keep layouts clean when data is missing.
Side-by-Side Code Comparison
| Content | Purpose | Example |
|---|---|---|
| CMS | Render dynamic website content | {% set rows = hubdb_table_rows(12345) %} + loop through data |
| Personalize messages | `{{ contact.firstname |
Feature Comparison: HubL in CMS vs Email
| Feature | HubL in CMS | HubL in Email |
|---|---|---|
| Primary Use | Build scalable, data-driven pages | Personalize email content |
| Data Sources | HubDB, blog data, modules | Contact properties, custom tokens |
| Loops | Full support for “for” and “while” | Limited (repeaters only) |
| Includes/Partials | Yes (include, macro) | Not supported |
| Programmability | Advanced (macros, filters, HubDB) | Moderate (programmable email in Enterprise) |
| Context | Website visitors | Individual recipients |
| Limitations | Subject to module support | No HubDB, no includes, email size limits |
Use Cases
CMS
- Product or service listing pages
- Dynamic landing pages powered by HubDB
- Blogs and gated membership content
- Personalized newsletters and promotions
- Lifecycle or nurture campaigns
- Transactional updates with tailored data
Key Takeaway
HubL has two distinct personalities:
- CMS HubL is your toolkit for building robust, reusable, and data-rich web experiences.
- Email HubL is your personalization engine, delivering messages that feel written for one person at a time.
When you respect these boundaries, your projects become cleaner, easier to maintain, and more effective, whether you’re scaling a website or sending targeted campaigns. Mastering this separation is the secret to unlocking HubSpot’s full potential.