GTM event implementation
Development steps to implement events in your application
Introduction
This chapter shows a guide to quickly implement tracking events. For this to work, we need the Google Tagmanager on the page and several events to be pushed to a datalayer-array. The pushing of these specified objects will kickoff a series of events that ultimately will lead to trusthworthy data that the owner of the system or site can use to analyse the behaviour of her/his guests with the user interface.
Events with payload
The default structure of the JSON objects to be pushed to the datalayer is this:
dataLayer.push({event: 'the_event_name', // requiredeventAction: 'the_action', // optionaleventLabel: 'the_label', // optionaleventProperties: {variable_A : 'value_A', // optionalvariable_B : 'value_B', // optionalvariable_C : 'value_C' // optional}});
The above is a hybryd approach of the strict event measuring of Google Analytics 4 and the event-category with an event-action and an event-label that is known from the measurement protocol of Google Universal Analytics. The only required variable is the 'event'.
The tags in GTM that use events holding the variable 'eventProperties' need to be configured to have a cleanup tag that empties/erases the content of this variable. Because of the lame nature of GTM's datalayer, the elements inside eventProperties are used by all subsequent tags that have this variable. Well, anyway, this variable needs to be reset every event.
The limits related to events are currently:
Limitations
As to all things on a human scale, there are limitations to these events (when related to Google Analytics.
- a maximum of 500 different "Event" names.
- a maximum of 25 custom parameters per event.
- each parameter value can be 100 characters long.
- a total limit of 25 user properties per property.
All events in row
For the implementation, the list below present the most common events on an site or app. This overview may be extended over time. Apart from the normal event structure (see above), there are 2 alternative sorts of events. That is:
- an event used to send variables, related to the user (so called user-properties)
- an event used to identify a pageview
Page views or Screen views
| event name | situation |
|---|---|
| page_view | on all pages |
Normally this code is outputted in the <head> because the variables are all known at serverside page rendering. This event is also needed on 'hash' or 'history' changes of the browser in cases of single pages apps. If data is made available in chuncks, please make sure there are unique but logical event names when pushing the values.
dataLayer.push({event: 'page_view',eventProperties: {page_virtual_path: '/category/page/',page_type: 'blog',page_id: '12',page_language: 'en',page_version: '2021-08-03 08:26:49',page_template: 'blog',page_modules: 'carrousel|intro|article|etc',software_environment: 'prod'}});
| property name | description |
|---|---|
| page_virtual_path | the virtual path when path needs overwriting |
| page_type | 'home', 'category', 'detail', 'searchresult', 'infopage', etc.. |
| page_id | the ID of the page (i.e. from the cms) |
| page_language | language of the page (not the client browserlanguage!) |
| page_version | versioning of pages (could be just the publication date) |
| page_template | the template name or ID |
| page_modules | the content blocks or structure that are on the page |
| software_environment | development cyclus, i.e. 'dev', 'test', 'acc', 'prod' |
User information
| event name | situation |
|---|---|
| user_info | on all pages |
Information on the specific user
dataLayer.push({event: 'user_info',userProperties: {id: '987654321',mail: '',loginState: 'recognized',status: 'novice',level: 'next'}});
| property name | description |
|---|---|
| user.id | the persistent user-id of the system/site/backend |
| user.mail | the email address of the user |
| user.loginState | 'anonymous', 'recognized', 'loggedIn', 'loggedOut' |
| user.status | indication of the status of the user |
| user.level | indication of the level or amount of points or .. |
Errors
| event name | situation |
|---|---|
| error | every time an error occurs |
The page returned with a server or system error. Implement on http-error pages and on system error pages. (also implement the 'all pages' tagging) This event can also be used for error event handling on a page or screen, i.e. in forms
dataLayer.push({event: 'error',eventAction: '#name#',eventLabel: '#destination#',eventProperties: {error_type: 'http',error_text: '#displayed error message#',error_value: '404',error_referrer: 'https://google.com',error_screen: '#screenname or ID#',error_formName: '#form name or ID#',error_formfieldName : '#field that produced the error#',error_formfieldInput : '#the input that caused the error#'}});
| property name | description |
|---|---|
| eventAction | the name of the button, the CTA or just the text on the button (beware of multilangual UI's) |
| eventLabel | destination. Can be a url or an inpage/inscreen link or an action to open an app or mail etc. |
| eventProperties | object containing custom properties, set or 'harvested' by the click i.e. 'download' when the button is for downloading a file |
| error_type | 'http', 'message', 'form', 'validation' etc. |
| error_text | the error-message as displayed in the UI (if any) |
| error_value | '403', '404', '500', 'error-name', 'error-message', etc |
| error_referrer | the referring url that resulted in the http error |
| error_screen | the screen name or ID that produced the error |
| error_formName | the name or ID of the form where the error occurred |
| error_formfieldName | the name of the formfield with wrong input |
| error_formfieldInput | the input of the formfield with the error |
Use all error variables you have available!
Button clicks
| event name | situation |
|---|---|
| button_click | every time a button is clicked |
Implement a general way of detecting button clicks and launch the dataLayer.push code before the button-action will be executed! The script needs a little time to be able to send the pixel or do whatever needs to be done, before the page/screen unloads and code is lost in space ...
dataLayer.push({event: 'button_click',eventAction: '#name#',eventLabel: '#destination#',eventProperties: {custom_property: '#value#'}});
| property name | description |
|---|---|
| eventAction | the name of the button, the CTA or just the text on the button (beware of multilangual UI's) |
| eventLabel | destination. Can be a url or an inpage/inscreen link or an action to open an app or mail etc. |
| eventProperties | object containing custom properties, set or 'harvested' by the click i.e. 'download' when the button is for downloading a file |
Hover or select
| event name | situation |
|---|---|
| select | every time an element is selected or hovered by the user |
Measure the mouse or finger hovering over an object or multiple selections of images or items on a page.
dataLayer.push({event: 'select',eventAction: '#item#',eventLabel: '#page-/form name#'}});
| property name | description |
|---|---|
| eventAction | the name of the item that is selected or hoovered over |
| eventLabel | the page or content element or form-name that originates the interaction |
Move or navigate
| event name | situation |
|---|---|
| navigate | every time an element is moved or used as navigation |
Measure the moving of a carrousel or the navigation inside a content element on a page.
dataLayer.push({event: 'navigate',eventAction: 'scroll_right',eventLabel: '#carrousel name#'}});
| property name | description |
|---|---|
| eventAction | the name of the item that is selected or hoovered over |
| eventLabel | the content element name that originates the interaction |
Video interactions
| event name | situation |
|---|---|
| video | every time the user interacts with video content |
When video's are embedded, we want to know when they are started and how much is seen by the user. Video-events are automatically send by GTM when the YouTube API is enabled.
dataLayer.push({event: 'video',eventAction: 'loaded',eventLabel: 'Hitchhikers Guide',eventProperties: {source: 'vimeo',autoplay: true}});
| property name | description |
|---|---|
| eventAction | 'loaded', 'start', 'progres 25%', 'progres 50%', 'progres 75%', 'complete' |
| eventLabel | the name of the video or title of the clip |
| eventProperties | object containing custom properties, relevant to the video |
Search actions
| event name | situation |
|---|---|
| search | every time the user performs a search |
Measure the search term.
dataLayer.push({event: 'search',eventAction: '#searchstring#',eventLabel: '#results#',eventProperties: {category: '#search category#'}});
| property name | description |
|---|---|
| eventAction | the searchstring (what is searched for) |
| eventLabel | the amount of results |
| eventProperties | object containing custom properties, relevant to the search |
| eventProperties.category | the category included in the search |