Tag Manager
Tag Manager
What are tags?
Tags are rule-driven JavaScript actions that execute on your website based on user behavior, page conditions, or custom triggers. They follow a simple flow:
trigger → filters → execute action
Benefits:
- Custom JavaScript execution — Run any JavaScript code based on conditions
- Conditional logic — Execute actions only when specific conditions are met
- Template support — Use dynamic content with
{{ }}macros - Flexible triggers — Page views, scroll, timer, clicks, form submissions, and more
SDK loading and initialization
Before executing Tag Manager commands, make sure the Hood SDK is initialized correctly. The required setup depends on whether the SDK is loaded asynchronously or synchronously.
Asynchronous loading
When the SDK is loaded using the async attribute, it may not be ready when the page first calls Hood(...). Add the initialization stub before the asynchronous SDK script so that calls are queued until the SDK finishes loading.
<!-- Hood initialization stub — required before the async SDK -->
<script>
window.HoodEngage = window.HoodEngage || [];
window.Hood = function () {
arguments._t = [Date.now(), performance.now()];
HoodEngage.push(arguments);
};
</script>
<!-- Async Hood SDK -->
<script async
src="https://sdk.ocmcore.com/sdk/ht-latest.js"
data-tag="YOUR_CONFIGURATION_KEY">
</script>
After the initialization stub is defined, Hood(...) calls can safely be placed below it, even if the SDK has not finished loading.
Hood(...) before an asynchronously loaded SDK unless the initialization stub has already been added. Otherwise, the browser may report that Hood is not defined.Synchronous loading
When the SDK is loaded without the async attribute, the browser waits for it to load and execute before continuing with the following scripts. In this case, the initialization stub is not required.
<!-- Sync Hood SDK -->
<script
src="https://sdk.ocmcore.com/sdk/ht-latest.js"
data-tag="YOUR_CONFIGURATION_KEY">
</script>
<script>
Hood('config', 'debug', true);
</script>
Make sure all Hood(...) calls are placed after the synchronous SDK script.
Tag types
- DOM Manipulation: Modify page elements for dynamic content updates, styling changes, and real-time page customization.
- Event Tracking: Track user interactions for analytics, conversion tracking, and data collection insights.
- Custom Actions: Execute JavaScript functions for complex business logic, integrations, and flexible automation.
- Content Injection: Add content to page for dynamic banners, notifications, and contextual messaging.
Tag configuration
i(string, required): Identifier - CSS selector or element reference for DOM manipulation.a(string, required): Action - DOM manipulation method to execute (e.g.,html,append,prepend,before,after,remove,empty,replaceContent).c(string, required): Content - Content to inject or template with{{ }}macros for dynamic values.triggers(array, required): Defines when a tag is eligible to execute (lifecycle, timing, user actions, element visibility). See Events and triggers.filters(array, optional): Defines who should see the tag using a rule engine (macros + operators). See Filtering.
Basic tag structure
{
"i": "#welcome-message",
"a": "html",
"c": "Welcome {{data.name}}!",
"triggers": [{ "type": "pageView" }],
"filters": [
{ "c": "{{data.segment}}", "o": "eq", "m": "new_user" }
]
}
Tag configuration options
Identifier (i)
CSS selector or element reference for DOM manipulation.
Supported selectors:
- ID selector:
#element-id - Class selector:
.element-class - Attribute selector:
[data-attribute="value"] - Complex selectors:
.parent .child,div:first-child - Multiple elements:
.multiple-elements(affects all matching elements)
Examples:
{ "i": "#welcome-banner" } // Single element by ID
{ "i": ".price-display" } // All elements with class
{ "i": "[data-track='button']" } // Elements with specific attribute
{ "i": ".product-card .title" } // Nested element selection
Validation: Element must exist in DOM when tag executes, otherwise action is skipped.
Action (a)
DOM manipulation method to execute on the target element. Uses the SDK’s built-in DOM manipulation functions.
Available actions:
html: Replace element content with HTML for dynamic content injection.replaceContent: Replace content and append new content for content updates with additional elements.empty: Remove all child elements to clear element content.append: Add content at the end of element to append new content.prepend: Add content at the beginning of element to insert content at start.before: Insert content before the element to add content before target.after: Insert content after the element to add content after target.remove: Remove the element from DOM to delete elements.
Examples:
{ "a": "html", "c": "<strong>Sale!</strong>" }
{ "a": "append", "c": "<div>New content</div>" }
{ "a": "empty" } // No content needed for empty action
{ "a": "remove" } // No content needed for remove action
Note: These actions use the SDK’s internal DOM manipulation system (df object) and work with the $ selector function. Custom actions are not supported - only the built-in methods listed above are available.
Content (c)
Content to inject or template with dynamic values.
Template support: Use {{ }} macros for dynamic content:
{{data.property}}- User data properties{{window.BW_INFO.t}}- Browser information{{url.searchParams.utm_source}}- URL parameters{{call.functionName()}}- Custom function calls
Examples:
{ "c": "Welcome {{data.name}}!" }
{ "c": "Price: ${{data.price}}" }
{ "c": "<div class='alert'>{{data.message}}</div>" }
{ "c": "{{call.getCurrentTime()}}" }
HTML vs Text:
- Use with
htmlfor HTML content - Use with
append/prependfor adding HTML elements - Use with
before/afterfor inserting HTML before/after elements
Tag configuration examples
Basic content update
{
"i": "#user-greeting",
"a": "html",
"c": "Hello {{data.name}}!",
"triggers": [{ "type": "pageView" }],
"filters": [
{ "c": "{{data.name}}", "o": "isset" }
]
}
Dynamic pricing display
{
"i": ".price-display",
"a": "html",
"c": "${{data.discounted_price}}",
"triggers": [{ "type": "pageView" }],
"filters": [
{ "c": "{{data.user_tier}}", "o": "eq", "m": "premium" }
]
}
Append new content
{
"i": "#product-list",
"a": "append",
"c": "<div class='new-product'>{{data.new_product}}</div>",
"triggers": [{ "type": "pageView" }],
"filters": [
{ "c": "{{data.new_product}}", "o": "isset" }
]
}
Remove elements
{
"i": "#outdated-banner",
"a": "remove",
"triggers": [{ "type": "pageView" }],
"filters": [
{ "c": "{{data.show_banner}}", "o": "eq", "m": "false" }
]
}
Advanced tag configurations
Multiple elements with same action
{
"i": ".product-title",
"a": "html",
"c": "{{data.product_name}} - Limited Time!",
"triggers": [{ "type": "pageView" }],
"filters": [
{ "c": "{{data.campaign_active}}", "o": "eq", "m": "true" }
]
}
Content insertion before elements
{
"i": "#checkout-form",
"a": "before",
"c": "<div class='discount-notice'>Use code: {{data.discount_code}}</div>",
"triggers": [{ "type": "formSubmit" }],
"filters": [
{ "c": "{{data.coupon_eligible}}", "o": "eq", "m": "true" }
]
}
Clear and replace content
{
"i": ".navigation-item",
"a": "replaceContent",
"c": "<span class='highlighted'>{{data.new_nav_text}}</span>",
"triggers": [{ "type": "pageView" }],
"filters": [
{ "c": "{{data.user_segment}}", "o": "eq", "m": "vip" }
]
}
Tag execution flow
Execution order
- Trigger evaluation - Check if trigger conditions are met
- Filter evaluation - Apply audience filters (if any)
- Element validation - Ensure target element exists
- Action execution - Execute the specified action
- Error handling - Log errors if execution fails
Error handling
Tags include built-in error handling:
// Automatic error handling
try {
const element = $(this.identifier);
if (!element || typeof element[this.actionName] !== 'function') {
throw new Error(`Invalid action or element not found`);
}
element[this.actionName](content);
} catch (error) {
console.error('Tag execution error:', error.message);
}
Common error scenarios:
- Element not found in DOM
- Invalid action method
- Template rendering errors
- Permission restrictions
Best practices
Performance optimization
Performance Tips
- Use specific selectors:
#idis faster than.classor complex selectors - Minimize DOM queries: Cache element references when possible
- Batch operations: Group related DOM manipulations
- Debounce triggers: Avoid excessive execution on scroll/resize events
- Test element existence: Always validate elements before manipulation
Security considerations
- Sanitize content: Avoid injecting unsanitized user data
- Validate inputs: Check data before using in templates
- Use textContent: Prefer
textContentoverinnerHTMLfor user data - CSP compliance: Ensure tags work with Content Security Policy
Debugging tags
The following examples assume that the Hood SDK has already been initialized. When using asynchronous loading, include the required initialization stub before calling Hood(...).
// Enable debug mode
Hood('config', 'debug', true);
// Check tag execution
Hood('on', 'tagExecuted', (tagId, result) => {
console.log('Tag executed:', tagId, result);
});
Complete configuration example
E-commerce personalization
{
"tag_config": {
"tags": {
"personalized-greeting": {
"i": "#welcome-message",
"a": "html",
"c": "Welcome back, {{data.name}}!",
"triggers": [{ "type": "pageView" }],
"filters": [
{ "c": "{{data.name}}", "o": "isset" },
{ "c": "{{data.returning_user}}", "o": "eq", "m": "true" }
]
},
"dynamic-pricing": {
"i": ".price-display",
"a": "html",
"c": "${{data.member_price}}",
"triggers": [{ "type": "pageView" }],
"filters": [
{ "c": "{{data.membership}}", "o": "eq", "m": "premium" }
]
},
"add-discount-banner": {
"i": "#product-info",
"a": "before",
"c": "<div class='discount-banner'>Special discount for {{data.name}}!</div>",
"triggers": [{ "type": "pageView" }],
"filters": [
{ "c": "{{data.show_discount}}", "o": "eq", "m": "true" }
]
}
}
}
}
Multi-step user journey
{
"tag_config": {
"tags": {
"step-1-welcome": {
"i": "#onboarding-step-1",
"a": "html",
"c": "<div class='step active'>Welcome, {{data.name}}!</div>",
"triggers": [{ "type": "pageView" }],
"filters": [
{ "c": "{{data.onboarding_step}}", "o": "eq", "m": "1" }
]
},
"step-2-features": {
"i": "#onboarding-step-2",
"a": "html",
"c": "<div class='step active'>Here are your features...</div>",
"triggers": [{ "type": "click", "config": { "selector": "#next-step" } }],
"filters": [
{ "c": "{{data.onboarding_step}}", "o": "eq", "m": "2" }
]
},
"step-3-complete": {
"i": "#onboarding-complete",
"a": "html",
"c": "<div class='step complete'>Congratulations! You're all set up, {{data.name}}!</div>",
"triggers": [{ "type": "click", "config": { "selector": "#finish-setup" } }],
"filters": [
{ "c": "{{data.onboarding_step}}", "o": "eq", "m": "3" }
]
}
}
}
}
Integration with other features
Tags + Modals
Tags can work alongside modals for complex user experiences:
{
"tag_config": {
"tags": {
"modal-trigger": {
"i": "#show-modal-button",
"a": "click",
"triggers": [{ "type": "click" }],
"filters": [
{ "c": "{{data.modal_eligible}}", "o": "eq", "m": "true" }
]
}
}
},
"modals_config": {
"modals": [{
"id": "follow-up-modal",
"template": "follow-up-template",
"triggers": [{ "type": "custom", "config": { "event": "modal-triggered" } }]
}]
}
}
Tags + Analytics
Tags can trigger analytics events:
{
"tag_config": {
"tags": {
"track-interaction": {
"i": "#interactive-element",
"a": "customActions.trackEvent",
"c": "element_interacted,{element: 'special-button', page: '{{url.path}}'}",
"triggers": [{ "type": "click" }]
}
}
}
}
Troubleshooting
If tags aren’t working as expected, try these solutions:
Hood is not defined?
- If the SDK is loaded asynchronously, verify that the initialization stub is included before the SDK script
- Make sure the initialization stub runs before any
Hood(...)call - If the SDK is loaded synchronously, place all
Hood(...)calls after the SDK script
Tag not executing?
- Verify the element exists in the DOM when the tag triggers
- Check your CSS selector syntax (use browser DevTools to test selectors)
- Ensure triggers are firing correctly (enable debug mode to see trigger events)
- Confirm filters aren’t blocking execution
Content not updating?
- Verify the action method is valid (
html,append,prepend,before,after,remove,empty,replaceContent) - Check that the target element supports the action (e.g., can’t append to a void element)
- Inspect the browser console for JavaScript errors
- Test the action manually in DevTools console
Template not rendering?
- Check
{{ }}syntax is correct (no typos, proper spacing) - Verify the data property exists and has a value
- Test macro resolution in debug mode
- Ensure data is available when the tag executes
Performance issues?
- Use specific selectors (ID selectors are fastest:
#element-id) - Avoid complex CSS selectors when possible
- Debounce scroll and resize triggers
- Batch multiple DOM operations together
- Consider using
requestAnimationFramefor animation-related tags
Debug mode
Enable debug mode to see detailed tag execution logs:
Hood('config', 'debug', true);
This will log:
- Tag execution attempts
- Element validation results
- Action execution outcomes
- Error details and stack traces