All data accessible to HubL lives inside HubSpot. External systems can be involved, but only indirectly. Data from third-party platforms must be brought into HubSpot through integrations or APIs before it can be used in templates. Regardless of its origin, if the data is not stored in HubSpot, HubL cannot access it.
Rather than memorizing an incomplete reference of available variables, understanding where data originates and why it's available in one context but not another leads to better architectural decisions. It also encourages developers to explore data that exists within HubSpot but is not fully documented.
Reference pages often list a handful of commonly used properties of a variable while omitting others that are still present at render time. Once you know where a variable is available, you can inspect its full structure by outputting it directly using a filter such as |pprint in supported contexts.
This inspection technique applies broadly across HubL data sources. For example, inspecting the content variable can reveal properties such as content.landingPage, which indicates whether the current page is a landing page. Using this property could allow templates to render landing-page-specific elements without relying on naming conventions or maintaining separate templates. The same inspection approach can be used elsewhere to uncover undocumented data, as long as the variable exists in the current rendering context.
With that in mind, data in HubSpot can be grouped into several distinct categories, each with its own scope and availability during rendering.
Portal & Platform Context consists of data based on the portal's configuration and the CMS interface. This data is generally accessible across templates, modules, pages, and emails, with some environment-specific exceptions, such as email templates having their own branding variables that differ from page and blog content.
Portal context includes data that is configured within the HubSpot portal itself and is shared across content. This data is defined outside individual pages, templates, and modules, and is typically managed through portal-level settings rather than the page editor.
Examples of portal context include global branding settings, navigation menus, company information, robots and indexing settings, search and membership URL paths, and analytics configuration. Although this data is editable, it is not tied to a specific piece of content and is intended to be reused across the site.
Platform context consists of values provided by HubSpot to describe the current rendering environment. These values are not configurable and instead reflect how, where, and under what conditions content is being rendered.
This includes information such as current locale and date, the active domain and portal ID, editor or preview state, and other environment-derived values. Platform context allows templates to adjust behavior based on rendering conditions without relying on content or portal configuration.
Page, blog, and email context includes data derived from the specific content being rendered. Some variables are shared across all three environments, while others expose different properties depending on whether the content is a page, blog, or email. Variables such as content, for example, return different structures based on the rendering context.
Across all three environments, this context includes high-level information such as publishing state, creation and update timestamps, metadata, authorship, and URL-related values.
Pages and blogs share additional context that is not available in email. This includes HTTP request data, built-in body classes, standard header and footer includes, language identifiers, and the logged-in state of the current visitor. These values exist because pages and blogs are rendered as part of a live website and can respond to browser-level and visitor-specific information.
Blog context extends page-level data with information specific to blog listings and posts. This includes listing and post metadata, pagination values, previous and next post relationships, listing type, tags, and comment data. These values are only available when rendering blog content and vary depending on whether the template is being used for a listing page or an individual post.
Email context is distinct due to the constraints of the email environment. Emails do not have access to request or visitor state and instead expose data required for delivery, compliance, and rendering within email clients. This includes subject lines, from and reply-to addresses, subscription and unsubscribe information, and variables for generating a view-as-page URL.
Template context influences how content is rendered, but it does not persist beyond the page using that template. This context exists only for the duration of rendering and is resolved at the template level before module logic is evaluated.
Template context is exposed through the context dictionary. Developers can define arbitrary keys on this object to pass values into section partials. Those values can then be referenced by modules within the partial to provide default field values when the module is rendered.
Module context is data HubL receives from a specific module instance. This data is accessed through the module variable and exists solely when that module is rendered on a page.
In most cases, module context is defined by the developer through the fields added to the module. Each field contributes its value to the module object using the field’s name as the key. More complex field types may also expose additional, field-specific properties. Image fields, for example, include structured metadata beyond a simple URL.
Module context is not fully siloed to the module itself. Module data is surfaced to the page or blog context through the content.widgets variable. This allows templates to inspect and conditionally respond to module data outside the module’s own scope, which can be useful for conditional rendering or template-level decisions
There are, however, important constraints. Only modules with stable, known IDs can be accessed reliably through content.widgets. Modules placed in drag-and-drop areas are assigned randomized IDs at render time, which makes direct access impractical. In addition, content.widgets only expose field values that have been assigned to the module after it has been added to a page or blog through the editor. Default values defined in the module’s field configuration are not included.
HubDB structured data consists of records stored in HubDB tables. Unlike portal, platform, or content context, HubDB data is not automatically available. It must be explicitly queried and is subject to portal-level feature restrictions.
Access to HubDB varies by content type and subscription level. Pages and blogs can query HubDB tables when the portal has Content Hub Professional or Enterprise, or Marketing Hub Enterprise. Email access is more limited. HubDB data can only be used in programmable email modules and requires Marketing Hub Enterprise.
HubDB exposes structured data through tables, rows, and columns, all of which can be queried and iterated over in HubL. In addition to row data, metadata about a table is available through the table_info object, including publish state, row count, and column definitions. This metadata can be used to inform rendering logic without querying individual rows.
When HubDB is paired with dynamic pages, additional variables become available. Values such as dynamic_page_hubdb_table_id and dynamic_page_hubdb_row provide direct access to the table and row responsible for generating the current page. These variables allow templates to render record-specific content without manually querying the table.
CRM object data consists of record-based objects stored in the HubSpot CRM. These objects are globally defined at the portal level, but access to their data during rendering is subject to portal permissions, content type, and privacy constraints.
Products, marketing events, and custom objects are broadly available for use in pages and blogs, and can also be accessed within programmable email modules when the portal has Marketing Hub Enterprise. Custom objects, which are defined by users within the portal, require Content Hub Enterprise to be able to create and access.
Other CRM objects, such as contacts, companies, deals, and tickets, are more restricted. These objects can only be accessed on pages and blogs that require a password or membership login and email (requiring programmable emails for advanced logic). These limitations exist to prevent exposing sensitive or personally identifiable data on publicly accessible content.
Most CRM objects must be queried explicitly before their data can be used. Queries can return a single object, multiple objects, or objects retrieved through associations with other records. However, some commonly used objects, such as contacts and companies, are also surfaced directly through variables like contact or company.
In CRM-driven dynamic pages, variables such as dynamic_page_crm_object_type_fqn and dynamic_page_crm_object provide access to the object type and record used to generate the page, allowing templates to render record-specific content without additional queries.
All these data sources listed define the boundaries of what HubL can access at render time. Knowing how each category differs in scope, availability, and limitations makes it easier to choose the appropriate data source for a given problem.