Setup: Traditional

This guide covers sites whose pages are rendered by dotCMS templates and layouts. If your front end is a separate application, see Headless setup instead.

Add the Tracking Call#


Analytics tracking is added by calling $!dotAnalytics.code() in your Velocity template, at the exact location where the <script> tag should appear — normally inside <head>. dotCMS builds the full script tag from your Content Analytics app configuration; you control where it lands.

<head>
  …
  $!dotAnalytics.code()
</head>

What the Call Returns#

  • On a LIVE page with the Content Analytics app configured for the site → the full analytics <script> tag.
  • In preview or edit mode, when no app is configured, or when analytics is disabled → an empty string. The $! silent syntax ensures nothing is printed.

What dotCMS Generates#


You never write this tag by hand. It is shown so you know what to expect on the page:

<script src="/ext/analytics/ca.min.js"
    data-analytics-auth="YOUR_SITE_AUTH"
    data-analytics-debug="false"
    data-analytics-auto-page-view="true"
    data-analytics-impressions="false"
    data-analytics-clicks="false"
    data-analytics-config='{…}'>
</script>

Configuration Options#


What the script does once it is on the page is not set in your template — it is set in the Content Analytics app, under Server-Rendered Pages Configuration, on the site you are configuring. The ViewTool decides where the script goes; these settings decide how it behaves, and they are what gets written into the tag shown above.

SettingWhat it doesDefault
Enable Auto Page Views autoPageViewTrack a page view on every page load.true
Enable Content Impressions contentImpressionTrack when content items become visible in the viewport.false
Enable Content Clicks contentClickTrack clicks on links and buttons inside content items.false
Enable Debug Mode debugLog analytics activity to the browser console.false

Advanced Configuration#

The four toggles cover what most sites need. For finer control — how events are batched, and how strict the impression threshold is — the same section of the app has an Advanced Configuration field that takes JSON. Whatever you put there is serialized into the data-analytics-config attribute of the generated script.

{
  "queue":       { "eventBatchSize": 15, "flushInterval": 5000 },
  "impressions": { "visibilityThreshold": 0.5, "dwellMs": 750, "maxNodes": 100 }
}
OptionMeaningDefault
queue.eventBatchSizeSend the batch once this many events are queued.15
queue.flushIntervalSend queued events at least this often (ms).5000
impressions.visibilityThresholdFraction of the element that must be visible (0–1).0.5
impressions.dwellMsHow long it must stay visible to count (ms).750
impressions.maxNodesMaximum content items observed for impressions on a page.100

Making Content Trackable#


On a published page, a rendered content item comes out looking like this. You never write it — it is shown so you can recognise it when inspecting a page:

<div class="dotcms-contentlet"
     data-dot-identifier="8a7d5e1f…"
     data-dot-inode="3c2b9f04…"
     data-dot-title="Spring Sale Hero"
     data-dot-type="Banner"
     data-dot-basetype="CONTENT">

  <a href="/signup" data-category="primary-cta">Start Free Trial</a>
  <button data-action="subscribe">Subscribe</button>
</div>

Inside that wrapper, only <a> and <button> elements are tracked for clicks. Any data-* attributes you put on them — like the two above — are captured with the event, which is the one place your own markup makes a difference.