> ## Documentation Index
> Fetch the complete documentation index at: https://docs.curator.interworks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Analytics Tracking

> Configure web analytics tracking in Curator using Google Analytics, Google Tag Manager, or Matomo to monitor user engagement and dashboard interactions.

Curator supports integration with popular web analytics platforms so administrators can track page views, user
engagement, and Dashboard interactions. Analytics tracking is configured in the Curator backend under
**Portal Settings > Analytics**.

## Supported Platforms

Curator supports the following analytics platforms. You can enable one or more simultaneously:

| Platform                               | Tracking Method                                     | User Identification                                        |
| -------------------------------------- | --------------------------------------------------- | ---------------------------------------------------------- |
| Google Analytics (Universal Analytics) | Page views and custom events via `analytics.js`     | Not sent                                                   |
| Google Analytics 4 (GA4)               | Page views and custom events via `gtag.js`          | `user_id` set to non-PII `analytics_id` UUID               |
| Google Tag Manager (GTM)               | Container-based tag management                      | `user_id` pushed to `dataLayer` as the `analytics_id` UUID |
| Matomo                                 | Page views, events, and site search via `matomo.js` | `setUserId` set to non-PII `analytics_id` UUID             |

## Configuration

Navigate to **Portal Settings > Analytics** in the Curator backend. All fields are optional. Fill in only the
fields for the platform(s) you use.

### Google Analytics (Universal Analytics)

**Google Analytics Tracking ID (Universal Analytics)** — Your Universal Analytics tracking ID
(e.g., `UA-XXXXXXXX-X`). Enables the `analytics.js` tracker, which sends an automatic page view on each
page load.

<Note>
  Universal Analytics was sunset by Google in July 2024. If you are setting up analytics tracking for the first
  time, use Google Analytics 4 or Google Tag Manager instead.
</Note>

### Google Analytics 4 (GA4)

**Google Analytics Tracking ID (Google Analytics 4)** — Your GA4 measurement ID
(e.g., `G-XXXXXXXXXX`). Enables the `gtag.js` tracker with automatic page views. If a user is logged in,
their non-PII `analytics_id` UUID is sent as the `user_id` property. See
[Correlating an `analytics_id` Back to a Curator User](#correlating-an-analytics_id-back-to-a-curator-user) for how
to look up the Curator user behind a UUID.

### Google Tag Manager (GTM)

**Google Analytics Tag Manager Container ID** — Your GTM container ID (e.g., `GTM-XXXX`). Loads the GTM
container script on every page. If a user is logged in, their non-PII `analytics_id` UUID is pushed to the
`dataLayer` as `user_id` before the container loads.

<Note>
  When using Google Tag Manager, you manage your analytics tags (including GA4) within GTM itself. You do not
  need to also fill in the GA4 field unless you want a separate, direct GA4 integration outside of GTM.
</Note>

### Matomo

* **Matomo Server URL** — The URL of your Matomo instance (e.g., `//matomo.example.com/`). Must include a
  trailing slash.
* **Matomo Site ID** — The numeric site ID configured in your Matomo instance (e.g., `1`).
* **Enable Matomo Heartbeat** — When enabled (default: on), Matomo tracks actual time spent on the page by
  monitoring whether the browser tab is active and in focus.

Both the Matomo Server URL and Matomo Site ID must be provided for Matomo tracking to activate. If a user is
logged in, their non-PII `analytics_id` UUID is sent via `setUserId`. Matomo link tracking and download
tracking are enabled automatically.

## Tracked Events

When analytics is configured, Curator automatically tracks user interactions as events. All events are sent to
every enabled analytics platform. Events use the category **Dashboard** and include the following actions:

| Event                             | Description                              |
| --------------------------------- | ---------------------------------------- |
| Custom View Applied               | User applied a saved Custom View         |
| Custom View Created               | User created a new Custom View           |
| Custom View Made Private          | User changed a Custom View to private    |
| Custom View Made Public           | User changed a Custom View to public     |
| Custom View Removed               | User deleted a Custom View               |
| Custom View Set as Default        | User set a Custom View as the default    |
| Data-Driven Alert Ceded           | User left a data-driven alert            |
| Data-Driven Alert Joined          | User joined a data-driven alert          |
| Download Workbook                 | User downloaded a workbook               |
| Exported All Summary Data         | User exported all summary data           |
| Exported CSV                      | User exported data as CSV                |
| Exported Data                     | User exported data                       |
| Exported Excel                    | User exported data as Excel              |
| Exported Image                    | User exported a Dashboard as an image    |
| Exported PDF                      | User exported a Dashboard as PDF         |
| Exported Powerpoint               | User exported a Dashboard as PowerPoint  |
| Exported Tableau-based Powerpoint | User exported a Tableau-based PowerPoint |
| Exported Workbook Summary Data    | User exported workbook summary data      |
| Favorited                         | User favorited a Dashboard               |
| Filter Applied                    | User applied a filter                    |
| Fullscreen                        | User entered fullscreen mode             |
| Parameter Applied                 | User applied a parameter                 |
| Paused                            | User paused automatic updates            |
| Powerpoint New Slide              | User added a new PowerPoint slide        |
| Powerpoint Slide Deleted          | User deleted a PowerPoint slide          |
| Powerpoint Slides Cleared         | User cleared all PowerPoint slides       |
| Print Dashboard Image             | User printed a Dashboard image           |
| Refresh Timer Start               | User started an automatic refresh timer  |
| Shared                            | User shared a Dashboard                  |
| Unfavorited                       | User unfavorited a Dashboard             |
| Unpaused                          | User resumed automatic updates           |

### Site Search Tracking

Curator also tracks site searches when a user uses the search feature:

* **Google Analytics 4:** Tracked using the built-in `search` event with a `search_term` parameter.
* **Matomo:** Tracked using the `trackSiteSearch` API with the search term, category, and result count.
* **Google Analytics (Universal Analytics):** Tracked as a page view to `/search?q={searchTerm}`. This only
  applies when Beta Search is enabled, since the `/search` route does not exist under the standard search.

### Custom Dimensions

Events include custom dimensions that provide additional context. These dimensions are sent when available:

| Dimension | GA4 Parameter                | Matomo Dimension |
| --------- | ---------------------------- | ---------------- |
| User      | `custom_parameter_user`      | `dimension4`     |
| Value     | `custom_parameter_value_str` | `dimension3`     |
| Workbook  | `custom_parameter_workbook`  | `dimension1`     |
| Worksheet | `custom_parameter_worksheet` | `dimension2`     |

<Note>
  For Matomo, custom dimensions must be configured in your Matomo instance with matching dimension IDs for the
  data to be recorded correctly.
</Note>

## User Identification with `analytics_id`

Curator sends a stable, non-PII UUID called `analytics_id` to GA4, GTM, and Matomo instead of the Curator
username. Usernames are often email addresses or real names, which Google Analytics' Terms of Service
prohibit sending as `user_id`. The `analytics_id` UUID avoids that restriction while still letting
administrators correlate analytics activity to a specific Curator user.

Key points:

* Every Curator frontend user has exactly one `analytics_id`, generated automatically when the user is
  created.
* The value is stable: it never changes for the life of the user record, so dashboards and audiences in
  GA4/Matomo remain consistent across sessions.
* Existing users were backfilled with an `analytics_id` during the upgrade migration, so no manual setup is
  required.

### Correlating an `analytics_id` Back to a Curator User

When you see a UUID in GA4, GTM, or Matomo and need to identify the underlying Curator user, query the
Curator User API. The `analytics_id` is included in the response of:

* `fetchUser` — current logged-in user
* `getUser` — user by token or `user_id`
* `listUsers` — paginated user list (use this to map UUIDs in bulk)
* `/user/info` — mobile auth response

For example, to pull a single page of users and their `analytics_id` values:

```bash theme={null}
curl -H "Authorization: Bearer <api-key>" \
    "https://curator.example.com/api/user/listUsers?num=100&pg=1"
```

Each user entry in the response includes `frontend_user_id`, `name`, `full_name`, `email`, and
`analytics_id`. Match the UUID you saw in GA4/Matomo to the `analytics_id` field to find the user.

For one-off lookups directly against the database, you can also query the `interworks_usermgmt_front_users`
table:

```sql theme={null}
SELECT id, name, full_name, email
FROM interworks_usermgmt_front_users
WHERE analytics_id = '<uuid-from-analytics>';
```

## Internal Logging

In addition to sending events to external analytics platforms, Curator logs all analytics events internally using
its client-side logging utility. These log entries are visible in the browser developer console when client-side
logging is enabled, which can be helpful for verifying that events are firing correctly during setup.

## Limitations

The events listed under [Tracked Events](#tracked-events) are the Dashboard-category interactions Curator sends to
your analytics platforms. Aside from those events, clicks on top-level primary nav file-type menu items also send
a **File / Download** event (see [Navigation and Menu Clicks](#navigation-and-menu-clicks) below). The vertical
side nav is included because it renders through the primary nav template (`menu::primarynav`); the horizontal side
nav is a separate code path that does not emit this event. Other interactions not in the list above are not
reported as Curator analytics events.

### Link Clicks and File Downloads

Curator does not fire its own analytics events for clicks on standard HTML links. File downloads triggered from
file-type menu items are a special case: Curator sends a **File / Download** event for them to some platforms, as
described below. How these interactions are captured depends on the platform:

* **Google Analytics 4 / Google Tag Manager** — Curator does not send link-click or file-download events to GA4
  or GTM. If your GA4 property has **Enhanced Measurement** enabled, GA4 may automatically capture outbound link
  clicks and file downloads. This is a GA4 property-level feature configured in your Google Analytics account,
  not a Curator feature, and its behavior depends entirely on your GA4 configuration.
* **Google Analytics (Universal Analytics)** — Curator does not send link-click events, but it does send a
  **File / Download** event (category `File`, action `Download`) when a user clicks a top-level primary nav
  file-type menu item — including the vertical side nav, which renders through the primary nav template
  (`menu::primarynav`), but not the horizontal side nav — as long as the Universal Analytics tracker (`ga`) is
  loaded. File-type items nested inside dropdown menus do not fire this event.
* **Matomo** — Curator enables Matomo's automatic link tracking and download tracking. Outbound link clicks are
  recorded by Matomo, and downloads — including clicks on top-level primary nav file-type menu items (and the
  vertical side nav, which renders through the primary nav template `menu::primarynav`, but not the horizontal
  side nav) — are tracked for elements Curator tags with the `tracking_download` CSS class. File-type items nested
  inside dropdown menus are not tagged and are not tracked.

Clicks that originate **inside an embedded iframe** — such as links or controls within a Tableau or Power BI
embed — cannot be captured by any script on the Curator page. Embedded dashboards are served from a different
origin, so the browser's same-origin policy prevents Curator's analytics integration, GA4 Enhanced Measurement,
Matomo link tracking, and any other page-level script from seeing interactions inside the frame.

### Navigation and Menu Clicks

Clicks on standard navigation and menu links are not sent as analytics events. Page views are recorded
automatically on each page load, so movement between pages is still reflected in your analytics, but the click
on the menu item itself is not reported as a separate event.

The exception is **top-level primary nav file-type menu items**: these are tagged with the `tracking_download`
CSS class, so a click fires a **File / Download** event (category `File`, action `Download`) to Matomo and to
Universal Analytics. Google Analytics 4 and Google Tag Manager do not receive this event. The vertical side nav
is included because it renders through the primary nav template (`menu::primarynav`); the horizontal side nav is
a separate code path (`sidenav.htm`) that builds menu items without a `url` key, so its file-type test never
resolves and no **File / Download** event fires for it at any depth.

File-type items nested as children under a primary nav parent are rendered through the dropdown template and do
not receive the `tracking_download` class, so no **File / Download** event fires for them.

## Custom Tracking Scripts (e.g., HotJar, FullStory)

Curator does not have built-in settings for session-recording or heatmap tools such as HotJar or FullStory.
You can still add these tools using either of the two mechanisms below.

### Through Google Tag Manager (recommended)

If you have configured a **Google Analytics Tag Manager Container ID** in **Portal Settings > Analytics**, add
the third-party script as a tag inside your GTM container. This keeps every custom script managed in one place.

1. Confirm a **Google Analytics Tag Manager Container ID** is set in **Portal Settings > Analytics**.
2. In your GTM container, create a new **Custom HTML** tag and paste in the tool's tracking snippet.
3. Set the tag's trigger to **All Pages**.
4. Submit and publish the GTM container.

### Through the theme Head Insert

If you are not using Google Tag Manager, you can paste a tracking snippet directly into the **Head Insert** field
found under the theme's custom styles settings in the Curator backend. The contents of this field are rendered
inside the `<head>` of every page. This is a good fit when you only need to add a single script and do not want
to set up a GTM container.

1. On the theme's **Global** tab, turn on **Enable Custom Styles (CSS / HTML inserts)**. This toggle is off by
   default. While it is off, the **Head Insert** field's label gains a **(Disabled)** suffix and a warning comment
   is shown beneath it; content pasted there is still not applied to the page until the toggle is on.
2. Open the **Custom Styles** tab (it is always visible) and paste the tool's tracking snippet into the
   **Head Insert** field.
3. Save the theme.

<Note>
  The **Head Insert** field is parsed as Twig before it is emitted into the page, so any `{{`, `{%`, or `{#`
  sequences in a pasted vendor snippet are interpreted as Twig rather than passed through as literal text. If your
  snippet contains those sequences (for example, a templating library's own placeholder syntax), it will not render
  verbatim and may fail silently. Add the script through Google Tag Manager instead, or escape the Twig delimiters
  using `{% verbatim %}...{% endverbatim %}`.
</Note>

<Note>
  Both approaches inject the tool's own script into the page. As with Curator's built-in analytics, these scripts
  run on the Curator page itself and cannot observe interactions inside embedded Tableau or Power BI iframes.
</Note>
