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
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
// 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:
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