Module: Www::TrackingHelper

Defined in:
app/helpers/www/tracking_helper.rb

Overview

Helper methods for trackable elements with Analytics integration

Include this helper where you need trackable phone links or other
tracked contact elements.

Examples:

Include in a controller

class PagesController < ApplicationController
  helper Www::TrackingHelper
end

Include in ApplicationHelper for site-wide availability

module ApplicationHelper
  include Www::TrackingHelper
end

Instance Method Summary collapse

Instance Method Details

#analytics_event_meta_tag(event, **props) ⇒ ActiveSupport::SafeBuffer

Declarative trigger for one-shot analytics events that fire on the
redirect target after a server-side action. Renders a meta tag that
Analytics.boot() reads on turbo:load and dispatches to the
matching track* method. See app/javascript/services/analytics.js
for the supported event registry.

Use this pattern when the event needs to fire on the page the user
lands on (post-Devise-redirect, post-form-submit redirect, etc.)
rather than on the page where they took the action — by the time
any JS would run on the action page, Devise has already redirected.

Examples:

In the post-registration redirect target view

<%= analytics_event_meta_tag(:registration_completed,
      accountId: current_account.id) if flash[:registered] %>

Parameters:

  • event (Symbol, String)

    event key matching one of Analytics.boot's
    registry entries — currently :registration_completed. Adding a new
    key requires both registering it here and wiring it in boot().

  • props (Hash)

    optional props passed as JSON to the JS track method.
    Keys map directly to the JS method's destructured params.

Returns:

  • (ActiveSupport::SafeBuffer)

    meta tag.



133
134
135
136
# File 'app/helpers/www/tracking_helper.rb', line 133

def analytics_event_meta_tag(event, **props)
  content = props.any? ? props.to_json : ''
  tag.meta(name: "analytics:#{event}", content: content)
end

Trackable phone link

Generates a phone link with consistent styling.

Examples:

Basic usage

<%= trackable_phone_link %>

With custom label

<%= trackable_phone_link(label: "Call Us Now") %>

Button style

<%= trackable_phone_link(style: :button) %>

With icon

<%= trackable_phone_link(icon: true) %>

Inline in text

<p>Call us at <%= trackable_phone_link %> for help.</p>

Parameters:

  • phone_number (String) (defaults to: nil)

    The phone number to display (formatted)

  • link_number (String) (defaults to: nil)

    The phone number for the tel: link (digits only, optional - defaults to PhoneNumbers::TOLLFREE_LINK)

  • label (String) (defaults to: nil)

    Optional custom label (defaults to formatted phone number)

  • class_names (String) (defaults to: nil)

    Additional CSS classes

  • style (Symbol) (defaults to: :default)

    Predefined style (:default, :button, :footer, :inline)

  • icon (Boolean) (defaults to: false)

    Whether to show phone icon (default: false)

  • html_options (Hash)

    Additional HTML attributes



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'app/helpers/www/tracking_helper.rb', line 47

def trackable_phone_link(phone_number: nil, link_number: nil, label: nil, class_names: nil, style: :default, icon: false, **html_options)
  # Use constants as defaults - client-side JS swaps these if ga_phone cookie exists
  display_number = phone_number || PhoneNumbers::TOLLFREE
  tel_number = link_number || PhoneNumbers::TOLLFREE_LINK

  # Build CSS classes based on style
  base_classes = %w[wy-click-to-call phone-text-link]
  style_classes = case style
                  when :button
                    %w[btn btn-outline-primary]
                  when :footer
                    %w[fs-4 text btn-link p-0 footer-link]
                  when :inline
                    %w[btn-link p-0]
                  else
                    %w[contact-phone]
                  end

  all_classes = (base_classes + style_classes + Array(class_names&.split)).compact.join(' ')

  # Build the link content
  content = if icon
              safe_join([fa_icon('phone', class: 'pe-1'), label || display_number])
            else
              label || display_number
            end

  # Build the link — aria-label must contain visible text (WCAG 2.5.3)
  opts = { rel: 'nofollow', class: all_classes }
  opts[:aria] = { label: "Call #{display_number}" } if label.blank?
  opts.merge!(html_options)

  link_to content, "tel:+#{tel_number}", **opts
end

#tracking_event_id_meta_tag(record) ⇒ ActiveSupport::SafeBuffer?

Emit the shared CAPI/pixel deduplication id as a meta tag so the
browser-side Analytics fan-out can read it via Analytics.serverEventId()
and pass it to every server-mirrored conversion event (Pinterest, OpenAI
Ads, etc.). The server-side reporters read the same tracking_event_id
off the record, so pixel and CAPI events match and dedupe correctly.

Call from any conversion-success view that has a record exposing
tracking_event_id — order confirmation, lead-form thank-you, instant
quote completion. No-ops when the record is nil or lacks the column
(legacy records pre-PR 3) so the helper is safe to drop in unconditionally.

Examples:

Order confirmation

<%= tracking_event_id_meta_tag(@order) %>

Lead form thank-you

<%= tracking_event_id_meta_tag(@opportunity) %>

Parameters:

  • record (#tracking_event_id, nil)

    Order, Opportunity, or any
    record that responds to tracking_event_id.

Returns:

  • (ActiveSupport::SafeBuffer, nil)

    meta tag, or nil when there's
    nothing to emit.



103
104
105
106
107
108
109
110
# File 'app/helpers/www/tracking_helper.rb', line 103

def tracking_event_id_meta_tag(record)
  return nil unless record.respond_to?(:tracking_event_id)

  event_id = record.tracking_event_id.presence
  return nil unless event_id

  tag.meta(name: 'tracking:event-id', content: event_id)
end