Skip to content

Amplitude Analytics ​

Overview ​

Amplitude is the primary product analytics platform in the Admin-Frontend. It tracks user behaviour across every DAM page — asset views, uploads, searches, bulk actions, image editing, portal configuration, member management, and more.

The implementation has two layers:

  • plugins/amplitude.js — initialises the SDK, adds a context-enrichment plugin that stamps every event with workspace/page context, and exposes $amplitude on every component
  • mixins/amplitude-analytics.js — provides typed tracking helper methods (trackActivity, trackImageEditor, trackFilterChange, etc.) consumed by pages and components

Setup & Initialisation ​

plugins/amplitude.js runs client-side only. On load it:

  1. Calls amplitude.init(apiKey, options) with the key from $config.amplitude.apiKey or AMPLITUDE_API_KEY env var
  2. Registers a context-enrichment plugin that auto-stamps every event (custom and autocaptured) with:
    • workspace_id, workspace_name (from live route params)
    • page_name, page_path (from vue-router)
    • origin_url, environment ('admin' or 'anonymous')
  3. Initialises Session Replay once deviceId and sessionId are ready
  4. Watches auth state — calls identifyFromAuthUser on login, reset on logout

Autocapture settings ​

FeatureStatusReason
Page viewsONStandard
SessionsONStandard
AttributionONStandard
Element interactionsONBy product decision — watch quota
Frustration interactionsONRage/dead clicks, low volume
Web VitalsONPerformance
Form interactionsOFFDialog-heavy UI; too noisy
File downloadsOFFDownloads use StreamSaver/blob, not anchors
Network trackingON (failures only, own hosts)API errors; S3 presigned URLs excluded

Event batching ​

Most events are queued client-side (batch size 10, flush after 5 s). The following events bypass the queue and fire immediately:

  • user logged-in
  • user login-failed

Note: Asset Upload Completed and Payment Completed appear only in the bypass allowlist in plugins/amplitude.js but are never fired from the frontend — they are reserved for future use.


User Identification ​

Called automatically on login via amplitudeAnalytics.identifyFromAuthUser(user).

javascript
// User properties sent to Amplitude (PII hashed before sending)
{
  email_hash: '<sha256>',         // email hashed — never raw email
  name_hash: '<sha256>',          // name hashed — never raw name
  user_type: 'admin' | 'user',
  subscription_user: true | false,
  created_at: '...',
  workspace_id: 42,
  default_workspace_id: 42,
  workspace_unique_id: 'abc123',
  workspace_name: 'ACME Brand',
  workspace_type: 'standard',
  is_trial_account: false,
  is_suspended: 0,
  screen_resolution: '1920x1080'
}

PII rule: email and name are hashed with SHA-256 (falls back to a fast integer hash on non-secure origins like http://localhost) before being sent to Amplitude. Raw PII never leaves the browser.


Custom Events Reference ​

All custom events are fired via this.$amplitude.track(eventName, properties) — either directly or through the mixin helpers. The context-enrichment plugin adds workspace_id, page_path, page_name, origin_url, and environment to every event automatically.

Naming pattern ​

"{entity} {verb}"            →  "asset viewed", "folder created"
"{entity} {noun}-{verb}"     →  "asset tags-added", "collage asset-removed"
"user {verb}"                →  "user logged-in", "user profile-updated"
"search {verb}"              →  "search performed", "search result-clicked"
"asset editor-{verb}"        →  "asset editor-opened", "asset editor-cropped"
"asset custom-fields-{kind}" →  "asset custom-fields-added"
"member {verb}"              →  "member invited", "member deactivated"
"workspace {noun}-{verb}"    →  "workspace domain-updated"
"portal {noun}-{verb}"       →  "portal banner-toggled", "portal created"

Asset events ​

All fired via trackActivity({ event: 'asset', sub_event: '...' }).

Event nameTriggerKey properties
asset viewedAsset card clicked / quick-view opened / detail page loadedasset_id, category_id?, collection_id?
asset downloadedAsset download button clickedasset_id, collection_id?
asset addedUpload completesasset_id, source
asset version-addedNew version uploaded for an existing assetasset_id
asset updateAsset metadata savedasset_id, fields_changed?
asset deletedAsset deleted (single or bulk)asset_id
asset archivedAsset archivedasset_id
asset movedAsset moved to another folderasset_id, category_id (destination)
asset duplicatedAsset duplicatedasset_id
asset sharedShare link createdasset_id, share_id
asset embeddedEmbed code generatedasset_id, share_id
asset embed-removedEmbed link removed from sharing managementasset_id, share_id
asset convertedFile format convertedasset_id
asset tags-addedTags added to assetasset_id, tag_id?
asset tags-removedTags removed from assetasset_id, tag_id?
asset visibility-updatedAsset portal visibility changed (portals added or removed)asset_id, portal_id, action ('added'/'removed')
asset version-previewedVersion previewed in Versions panelasset_id, version_id
asset version-downloadedSpecific version downloaded from Versions panelasset_id, version_id
asset version-deletedAsset version deletedasset_id, version_id
asset version-restoredAsset version restoredasset_id, version_id
asset upload-failedUpload errorasset_id?, source

Examples:

javascript
// Single asset viewed from a folder
this.trackActivity({
  event: 'asset',
  sub_event: 'viewed',
  asset_id: [123],
  category_id: [456],
})

// Bulk delete (3 assets)
this.trackActivity(
  { event: 'asset', sub_event: 'deleted', asset_id: [1, 2, 3] },
  { ...this.selectionMethodFor(3) }   // adds selection_method: 'shift-click' etc.
)

// Portal visibility change (via trackVisibilityChange helper)
this.trackVisibilityChange(
  { event: 'asset', sub_event: 'visibility-updated', asset_id: [assetId] },
  [{ id: 1 }, { id: 2 }],            // portals before
  [{ id: 2 }, { id: 3 }, { id: 4 }], // portals after
)
// Fires:
// "asset visibility-updated" { asset_id: ['42'], portal_id: ['3','4'], action: 'added' }
// "asset visibility-updated" { asset_id: ['42'], portal_id: ['1'], action: 'removed' }

Collage events ​

Event nameTriggerKey properties
collage viewedCollage detail page loadedcollection_id
collage downloadedCollage downloadedcollection_id, asset_id[]
collage createdNew collage createdcollection_id, asset_id[]?
collage updateCollage renamed/updatedcollection_id, fields_changed?
collage deletedCollage deletedcollection_id
collage asset-addedAsset added to collagecollection_id, asset_id
collage asset-removedAsset removed from collagecollection_id, asset_id
collage visibility-updatedCollage portal visibility changedcollection_id, portal_id, action
collage sharedCollage share link createdcollection_id, share_id

Folder events ​

Event nameTriggerKey properties
folder viewedFolder page loadedcategory_id
folder downloadedFolder assets downloadedcategory_id
folder createdNew folder createdcategory_id
folder updateFolder renamed/updatedcategory_id, fields_changed?
folder deletedFolder deletedcategory_id, assets_affected, subfolders_affected
folder movedFolder movedcategory_id
folder sharedFolder share link createdcategory_id, share_id
folder visibility-updatedFolder portal visibility changedcategory_id, portal_id, action
javascript
// Bulk folder delete — includes cascade size
const cascade = this.cascadeSize(foldersToDelete)
this.trackActivity(
  { event: 'folder', sub_event: 'deleted', category_id: folderIds },
  cascade   // adds assets_affected, subfolders_affected
)

Shared / anonymous events ​

Used on external share pages. environment is always 'anonymous'.

Event nameTriggerKey properties
shared viewedAnonymous user views shared assetshare_id, asset_id?
shared downloadedAnonymous user downloads shared assetshare_id, asset_id?
shared link-updatedShare link settings updated (expiry, password, etc.)share_id
shared password-verifiedShare password entered correctlyshare_id
shared password-failedShare password entered incorrectlyshare_id

Image editor events ​

Tracked via trackImageEditor(verb, properties) — goes directly to $amplitude.track. Event name: "asset editor-{verb}".

Event nameWhen fired
asset editor-openedUser opens the image editor tab on an asset
asset editor-croppedUser applies a crop
asset editor-rotatedUser rotates the image
asset editor-flippedUser flips horizontally or vertically
asset editor-resizedUser resizes the image
asset editor-downloadedUser exports / saves the edited image
asset editor-resetUser resets to the original
asset editor-format-changedUser changes the output format
javascript
// Editor opened
this.trackImageEditor('opened', {
  asset_id: this.file.id,
  file_type: 'image/jpeg',
})

// After applying a crop
this.trackImageEditor('cropped', { asset_id: this.assetId })

// After rotating
this.trackImageEditor('rotated', { asset_id: this.assetId })

Custom fields events ​

Tracked via trackCustomFieldsUpdated(assetIds, fields, isMultiple, forcedKind). Groups changes by kind and fires one event per group.

Event nameWhen
asset custom-fields-addedA custom field value is set for the first time
asset custom-fields-updatedAn existing custom field value is changed
asset custom-fields-removedA custom field value is cleared
javascript
this.trackCustomFieldsUpdated(
  [asset.id],    // asset IDs
  changedFields, // array of field objects from API
  false,         // isMultiple — true for bulk edits
)
// Fires e.g.:
// "asset custom-fields-added" { asset_id: ['42'], fields_changed: ['Brand'], field_count: 1, field_values: ['Brand=ACME'] }

Search events ​

Event nameWhenProperties
search performedSearch executes (on query change or filter update)query, has_query, result_count_assets, result_count_collages, result_count_folders, result_count_total, has_results, active_filter_types, filter_count, active_tab, trigger
search result-clickedUser clicks a search resultresult_type ('asset'/'folder'/'collage'), rank (1-based position), results_loaded
search filter-appliedUser adds or removes a search filterfilter_type, action ('add'/'remove'), filter_count_after
javascript
// Fired directly via $amplitude.track in search.vue
this.$amplitude.track('search performed', {
  query: 'brand logo',
  has_query: true,
  result_count_assets: 12,
  result_count_collages: 2,
  result_count_folders: 1,
  result_count_total: 15,
  has_results: true,
  active_filter_types: ['file_type'],
  filter_count: 1,
  active_tab: 'assets',
  trigger: 'keystroke',
})

View mode event ​

Event nameProperties
user view-mode-changedfrom_mode, to_mode, scope (page identifier)
javascript
this.trackViewModeChange('list', 'grid', 'folders-detail')
// → "user view-mode-changed" { from_mode: 'grid', to_mode: 'list', scope: 'folders-detail' }

The current view mode is also stored as an Amplitude user property (view_mode) via setViewModeProperty.


Trash events ​

Event nameWhenProperties
trash permanently-deletedUser empties trash or permanently deletes selected items—
trash restoredUser restores items from trash—

User / auth events ​

Fired via direct $amplitude.track calls on auth pages and profile settings.

Event nameWhenSource
user logged-inSuccessful login (password, social, or external verify)pages/index.vue, pages/social-login.vue, pages/.../external/verify.vue
user login-failedFailed login attemptsame
user password-reset-requestedForgot-password form submittedpages/forgot-password.vue
user password-reset-request-failedForgot-password request failedsame
user password-setPassword set on the password-setup pagepages/password-setup.vue
user invitation-acceptedUser accepts an invitation via generate-passwordpages/generate-password.vue
user invitation-accept-failedInvitation accept failedsame
user access-requestedExternal user submits access requestpages/.../external/request-access.vue
user access-request-failedAccess request failedsame
user profile-updatedUser updates their profile settingscomponents/dam/Profile/ProfileSetting.vue
user password-changedUser changes their password from profilesame
user profile-image-updatedUser uploads a new profile photocomponents/dam/Dialogs/Org-Settings/LogoEditDialog.vue
user notification-pref-updatedUser changes notification preferencescomponents/dam/Profile/NotificationSetting.vue
user passkey-addedPasskey registeredcomponents/dam/Profile/ProfileSetting.vue
user passkey-add-failedPasskey registration failedsame
user passkey-removedPasskey removedsame
user support-pin-generatedSupport PIN generatedsame
user support-session-terminatedSupport session terminatedsame
user support-sessions-clearedAll support sessions clearedsame
user view-mode-changedUser switches grid / list / mosaicmixins/amplitude-analytics.js

Member management events ​

Fired from workspace user-management pages and dialogs.

Event nameWhenSource
member addedAdmin adds a new member directlycomponents/dam/Dialogs/Org-Settings/AdminUserDialog.vue
member invitedAdmin sends an email invitationsame
member updatedAdmin updates member role or detailssame
member activatedAdmin re-activates a suspended memberpages/.../workspace-settings/user/list.vue, ActivateUserDialog.vue
member deactivatedAdmin deactivates a memberpages/.../workspace-settings/user/list.vue
member invite-resentAdmin resends a pending invitationsame
member password-resetAdmin triggers a password reset for a membersame

Workspace management events ​

Fired from workspace settings pages.

Event nameWhenSource
workspace createdNew workspace createdpages/create-workspace.vue
workspace settings-updatedGeneral workspace settings savedpages/.../workspace-settings/index.vue
workspace instance-settings-updatedDAM instance settings savedsame
workspace domain-updatedCustom domain savedsame
workspace domain-verifiedDomain verified successfullysame
workspace domain-verify-failedDomain verification failedsame
workspace custom-field-toggledCustom field enabled or disabledpages/.../workspace-settings/custom-fields/index.vue
workspace custom-field-deletedCustom field deletedsame
workspace notifications-toggledGlobal notification setting toggledpages/.../workspace-settings/dam/_instance_id/notifications/index.vue
workspace notification-prefs-updatedNotification preferences savedsame
workspace logo-updatedWorkspace logo uploadedcomponents/dam/Dialogs/Org-Settings/LogoEditDialog.vue
workspace favicon-updatedWorkspace favicon uploadedsame
workspace owner-changedWorkspace ownership transferredcomponents/dam/Dialogs/Org-Settings/WorkspaceOwnerDialog.vue
guest url-copiedExternal guest URL copied from user listpages/.../workspace-settings/external-user/list.vue
feedback submittedUser submits feedbackpages/.../feedback/index.vue
subscription canceledTrial account or subscription canceledcomponents/dam/Dialogs/subscription/DeleteTrialAccountDialog.vue

Portal management events ​

All fired via direct $amplitude.track — portal config is not asset transaction activity.

Portal lifecycle:

Event nameWhenSource
portal createdNew portal createdcomponents/dam/Dialogs/CreatePortalDialog.vue
portal branding-updatedPortal branding settings savedpages/.../workspace-settings/dam/_instance_id/index.vue
portal settings-updatedGeneral portal settings savedcomponents/dam/Settings/CollageSettings.vue
portal theme-updatedPortal colour theme changedsame
portal logo-updatedPortal logo uploadedsame
portal favicon-updatedPortal favicon uploadedsame
portal visibility-changedPortal published/unpublishedsame

Portal users:

Event nameWhenSource
portal invite-resentPortal user invitation resentpages/.../workspace-settings/portals/users/index.vue
portal user-deactivatedPortal user deactivatedsame
portal invite-deletedPortal invitation deletedsame
portal user-activatedPortal user reactivatedsame
portal user-password-resetPortal user password reset by adminsame

Portal banners:

Event nameWhenProperties
portal banner-createdNew banner addedinstance_id, banner_id
portal banner-updatedBanner editedinstance_id, banner_id
portal banner-toggledBanner activated or deactivatedinstance_id, banner_id, is_active
portal banner-deletedBanner deletedinstance_id, banner_id, banners_remaining
portal banners-reorderedAdmin drags to reorder bannersinstance_id, banner_count

Portal tiles:

Event nameWhenProperties
portal tile-createdNew tile addedinstance_id, tile_id
portal tile-updatedTile editedinstance_id, tile_id
portal tile-toggledTile activated or deactivatedinstance_id, tile_id, is_active
portal tile-deletedTile deletedinstance_id, tile_id, tiles_remaining
portal tiles-reorderedAdmin drags to reorder tilesinstance_id, tile_count
portal slider-toggledSlider mode enabled or disabledinstance_id, is_slider

portal banners-reordered and portal tiles-reordered only fire on genuine user drags — reorders triggered as a side effect of add/delete are suppressed.


Mixin Methods Reference ​

Registered globally via plugins/branding.js. Can also be mixed in locally: mixins: [amplitudeAnalytics].

MethodSignaturePurpose
trackActivity(payload, extraProperties?)Main tracking method — constructs event name from payload.event + payload.sub_event
trackImageEditor(verb, properties?)Tracks image editor actions as "asset editor-{verb}"
trackCustomFieldsUpdated(assetIds, fields, isMultiple?, forcedKind?)Tracks custom field add/update/remove grouped by kind
trackViewModeChange(mode, previous?, identifier?)Fires "user view-mode-changed" and updates user property
trackSearchResultClick(resultType, item, list)Fires "search result-clicked" with position rank
trackFilterChange(nextList)Fires "search filter-applied" on each filter type delta
trackVisibilityChange(activity, before, after, extra?)Fires visibility event split by portal IDs added/removed
recordSelectionMethod(method)Records how items were selected ('shift-click', 'checkbox', etc.)
selectionMethodFor(count) → {} or { selection_method }Returns selection_method property for bulk events
changedFields(pairs) → string[]Returns keys where before !== after — used to build fields_changed properties
cascadeSize(items) → { assets_affected, subfolders_affected }Computes cascade counts for folder delete/move events
syncViewMode(mode)Updates Amplitude user property only when mode actually changed

Property Allowlist ​

trackActivity passes the payload through an allowlist — only relevant entity IDs are forwarded per event type.

event valueAllowed keys from payload
assetasset_id, category_id, collection_id, version_id, share_id, tag_id
collagecollection_id, asset_id, share_id, category_id
foldercategory_id, asset_id, share_id
sharedshare_id, asset_id, category_id, collection_id
Allsource (common key)

All IDs are normalised to strings by the enrichment plugin (normalizeIdProperties) to prevent the same ID arriving as 42 in one event and "42" in the next.


Session Replay ​

Amplitude Session Replay is initialised after the main SDK is ready (plugins/amplitude-session-replay.js). Sampling rate is controlled by AMPLITUDE_SESSION_REPLAY_SAMPLE_RATE env var (0 = disabled). The session ID is re-synced after every navigation via router.afterEach.