---
# System prepended metadata

title: 'Hans Anders: Developer Instructions'

---

# Hans Anders: Developer Instructions

## Table of Contents

[TOC]


## Basics
### GTM code snippet NL
The default GTM client side container snippet needs to be active on every page and preferably on related pages loaded through iFrames. Paste this code as high in the **<head>** of all pages as possible and / or add the GTM container ID to external extensions / applications injecting the GTM snippet.  
```javascript
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-5KKFRJ');</script>
<!-- End Google Tag Manager -->
```
Additionally, paste this code immediately after the opening **<body>** tag:
```javascript
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5KKFRJ"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
```

### GTM code snippet BE
The default GTM client side container snippet needs to be active on every page and preferably on related pages loaded through iFrames. Paste this code as high in the **<head>** of all pages as possible and / or add the GTM container ID to external extensions / applications injecting the GTM snippet.  
```javascript
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-NFD48J');</script>
<!-- End Google Tag Manager -->
```
Additionally, paste this code immediately after the opening **<body>** tag:
```javascript
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NFD48J"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
```



### Data Layer per page
On each page it is required to implement a generic dataLayer variable which needs to be filled with relevant information form the data layer push below. If a certain value is unknown, the value can be an empty string. The data layer should be placed **above** the Google Tag Manager script. 

The following data layer has to be filled at every page:
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event': 'dataLayerInit',              
   'user': user_object,
   'page': page_object,
   'cart': cart_object
})
</script>
```


### User object per page
When a page loads, the data layer has to contain user object that holds the following information:
``` javascript
{
'consent': true,                        // true, false or null
'userId': 'user_id_hashed_sha256',        // SHA-256 hashed unique user id from backend 
// The DL contains userId which needs to be removed
'email_sha256': 'email_hashed_sha256',    // SHA-256 hashed e-mail address for logged in users
'visitor': 'external',                    // either external or internal
'visitorType': 'visitor_type'             // either logged in or not logged in
}
```
![](https://i.imgur.com/bCeJVXR.png)




### Page object per page
The data layer event **pageView** has to be removed. Instead, when a page loads, the data layer has to contain page object that holds the following information:
``` javascript
{
 'pageType': 'page_type',                 // already exists in the DL (for 404 pages pageType is NotFound) 
 'contentType': 'content_type',           // already exists in the DL 
 'currency': 'website_currency',          // ISO curency code
 'language': 'website_language'           // ISO 639-1 language code
}
```
![](https://i.imgur.com/cYxKZdx.jpg)




### Cart object per page
When there are products in the cart on each page **except purchase** the data layer has to contain cart object, which holds the data of the active car. On the purchase page the object cart has to be empty again. Besides that, on every cart mutation (add or remove products), the cart has to be updated. 
``` javascript
{
 'id': '000000000002212602',
 'name': 'DYSYGN B000928',
 'price': 119.00,
 'quantity': 1,
 'brand': 'DYSYGN',
 'category': 'Brillen',               
 'variant': 'Alle brillen'
}
```
    



## Ecommerce events
### productVisible
When a product is shown in a page listing then the following dataLayer has to be filled: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'productVisible',
   'ecommerce': {
    'currencyCode': 'currency_code',  
    'impressions': [ {
        'id': '000000000002212602',
        'name': 'DYSYGN B000928',
        'price': 119.00,
        'brand': 'DYSYGN',
        'category': 'Brillen',               
        'variant': 'Alle brillen',
        'list': 'listname'             //HA team to provide better naming for different lists on the website
    },
      { 'id': '000000000002210514',
        'name': 'Calvin Klein Jeans 799',
        'price': 99.00,
        'brand': 'Calvin Klein Jeans',
        'category': 'Zonnebrillen',               
        'variant': 'Zonnebrillen op sterkte',
        'list': 'listname'           //HA team to provide better naming for different lists on the website
      }]
   }
});
</script>
```
*****Products are grouped in batches, based on which product are displayed, when the user scrolls new event is pushed with the products in view port. This is also how currently things are measured in DataLayer****

### productClick
When a product tile is clicked in a page listing then the following dataLayer has to be filled: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'productClick',
   'ecommerce': {
    'currencyCode': 'currency_code',  
    'click':  {
        'actionField': {'list': 'listname'},
        'products': [{
        'id': '000000000002212602',
        'name': 'DYSYGN B000928',
        'price': 119.00,
        'brand': 'DYSYGN',
        'category': 'Brillen',               
        'variant': 'Alle brillen',
        'list': 'listname',             //HA team to provide better naming for different lists on the website
        'position':'1'                  //Position of the product in the list where clicked
   
      }]
   }
   }
});
</script>
```
### productDetail (currently in DataLayer as View Content)
When a product is viewed on a PDP, then the following dataLayer has to be filled: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'productDetail',
   'ecommerce': {
    'currencyCode': 'currency_code',  
    'detail':  {
        'products': [{
        'id': '000000000002212602',
        'name': 'DYSYGN B000928',
        'price': 119.00,
        'brand': 'DYSYGN',
        'category': 'Brillen',               
        'variant': 'Alle brillen'
   
      }]
   }
   }
});
</script>
```
### addToCart
When a product is successfully added to the cart, or the quantity is successfully increased then the following dataLayer has to be filled: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'addToCart',
   'ecommerce': {
    'currencyCode': 'currency_code',  
    'add': {                     
      'products': [{
        'id': '000000000002212602',
        'name': 'DYSYGN B000928',
        'price': 119.00,
        'brand': 'DYSYGN',
        'category': 'Brillen',               
        'variant': 'Alle brillen',
        'quantity': 1           
      }]
   }
});
</script>
```
***On the purchase page, the object should be empty again**
     
### addToCart (with steps) - For Glasses and Lensen, not for Sunglasses and Hearing aids
When a product is added to the cart by first compliting several steps, then the following dataLayer has to be filled: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'gtm.trackEvent',
    'eventCategory': "ecommerce",
    'eventAction': "addToCart",
    'eventLabel': "step1",                 //step 1,2 or 3
     
      }]
   }
});
</script>
```

**Step 1 - Click on In winkelmand**
    ![](https://i.imgur.com/fbtbR6e.png)
**Step 2 - Click on Verder**
    ![](https://i.imgur.com/pnrbhQk.png)
**Step 3 - Click on Verder**
    ![](https://i.imgur.com/pRQ7Z1f.png)



    
### removeFromCart
When a product is successfully removed from the cart, or the quantity is successfully decreased then the following dataLayer has to be filled: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'removeFromCart',
   'ecommerce': {
    'currencyCode': 'currency_code',  
    'remove': {                     
      'products': [{
        'id': '000000000002212602',
        'name': 'DYSYGN B000928',
        'price': 119.00,
        'brand': 'DYSYGN',
        'category': 'Brillen',               
        'variant': 'Alle brillen',
        'quantity': 1           
      }]
   }
});
</script>
```
    

### Virtueel passen
When a visitor clickes on Virtueel passen button next to the product, then the following dataLayer has to be filled: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'virtueelPassen',
  'eventCategory': 'ecommerce', 
  'eventAction': 'Virtueel passen',  
  'eventLabel': 'PDP'        //Where the button was clicked, either PDP or PLP
   
});
</script>
```
    
### Close VTO
When a visitor clickes on exit button to close the VTO, then the following dataLayer has to be filled: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'closeVTO',
  'eventCategory': 'ecommerce', 
  'eventAction': 'Close VTO',  
  'eventLabel': 'Calvin Klein Jeans 799'      //Name of the product 
   
});
</script>
```
    
### VTO unavailable
If VTO is unavailable, then the following dataLayer has to be filled: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'VTOunavailable',
  'eventCategory': 'ecommerce', 
  'eventAction': 'VTO unavailable',  
  'eventLabel': 'Calvin Klein Jeans 799'      //Name of the product 
   
});
</script>
```
  ![](https://i.imgur.com/lM5WBBC.png)
  
### Pas in the winkel
When a visitor clickes on Pas in the winkel button next to the product, then the following dataLayer has to be filled: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'passInTheWinkel',
  'eventCategory': 'ecommerce', 
  'eventAction': 'Pas in the winkel',  
  'eventLabel': 'Calvin Klein Jeans 799'      //Name of the product 
   
});
</script>
```


### Checkout guide
#### This guide will help you implement tracking for the  checkout page. With the guide we have a new syntax that will be compatible with both the old setup as well as the new GA4 setup
    
![](https://i.imgur.com/5M1204n.png)

**Product object**
In this guide we will refer to the product object. The product object has the following syntax:

**Basic product data**

``` javascript
{   'id':'', //Id of the product
	'name':'', //Name of the product
	'brand':'', //Brand of the product
	'variant': '', //Variant of the product
	'category':'',  //Category of the product
	'price' : '', //Price of the product",
	...

     
	}

```
    
**Line item product data**
The line item product data is basically the basic product data with the quantity. 

``` javascript
{   ...basicProductData,
	'quantity':'', //Quantity of the product
}

```
    
**Cart page**
On the cart page there are two types of tracking:

We want to track the products that are currently in the cart.
We want to track the products in the cross-sell section

**Checkout step**
Tracking the checkout step with the products requires the following code:
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'view_cart',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Product checkout - Cart',
   	    'funnelName':'Product checkout',
   	    'funnelStep':'Cart',
   	    'isRepeatOrder':'0',
    	'items':[{
        	...lineItemProductData
    	}]
	}
});


     
</script>
```
    
**Cross sell products**
For each list item, you can add the following data-attribute. GTM will handle the viewability of being in view for 1 second 50%.

This means that the items-array will contain one item.
    
``` javascript
data-track-view='{
	'event': 'view_item_list',
	'data': {
		'eventCategory': 'User interaction',
		'eventAction': 'Product list view',
		'items': [{
			...basicProductData,
			'item_list_name':'Cross sell'
		}]
	}
}'
```
The moment the user clicks on the product, the following code should be triggered:
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'select_item',
	'data': {
		'eventCategory':'User interaction',
		'eventAction': 'Product list click',
		'items': [{
			...basicProductData,
			'item_list_name':'Cross sell'
		}]
	}
})
    
</script>
```
If the user clicks on the add to cart, then after the select_item event, the following event should be triggered:
    
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'add_to_cart',
	'data': {
		'eventCategory': 'User interaction',
		'eventAction': 'Product add to cart',
		'items': [{
			...basicProductData
		}]
	}
})


</script>
```

Changing quantities
If the user change the quantity, the difference should be tracked. This is either an add to cart or a remove from cart.
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'add_to_cart',
	'data': {
		'eventCategory': 'User interaction',
		'eventAction': 'Product add to cart',
		'items': [{
			...basicProductData
		}]
	}
})


</script>
```
    
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'remove_from_cart',
	'data': {
		'eventCategory': 'User interaction',
		'eventAction': 'Product remove from cart',
		'items': [{
			...basicProductData
		}]
	}
})


</script>
```
    
**Checkout pages**
Tracking the checkout step with the products requires the following code, regardless whether the user was logged in or not:
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'begin_checkout',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Product checkout - Personal information',
   	    'funnelName':'Product checkout',
   	    'funnelStep':'Personal information',
   	    'isRepeatOrder':'0',
    	'items':[{
        	...lineItemProductData
    	}]
	}
});


     
</script>
```
    
If the user was logged in or logs in at the top of the information page. The following event should be triggered:

``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'enterCheckoutLoginFlow',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Enter checkout login flow'
	}
});
    
</script>
```
    
If the user is not logged in, the shipping and payment options should be picked. The moment a user selects a field from pick-up, the following code should be triggered:
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'add_shipping_info',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Product checkout - Shipping information',
   	    'funnelName':'Product checkout',
   	    'funnelStep':'Shipping information',
   	    'isRepeatOrder':'0',
    	'items':[{
        	...lineItemProductData
    	}]
	}
});


     
</script>
```
    
If the user is not logged in, the payment page will be shown:
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'add_payment_info',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Product Checkout - Payment information',
   	    'funnelName':'Product checkout',
   	    'funnelStep':'Payment information',
   	    'isRepeatOrder':'0',
    	'items':[{
        	...lineItemProductData
    	}]
	}
});


     
</script>
```
    
**Purchase**
Tracking the checkout step with the products requires the following code::
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'purchase',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Product checkout - Purchase',
    	'funnelName': 'Product checkout',
    	'funnelStep': 'Success',
   	    'isRepeatOrder':'0',
    	'eventValue': '35.43', //Transaction revenue
    	'purchase': {
        	'id": 'T12345',
        	'tax': 4.90,
        	'shipping': 5.99,
        	'couponCode':'',
        	'paymentMethod':',
        	'shippingMethod':'
    	},
    	'items': [{
            	...lineItemProductData
        	}
    	]
	}
});
     
</script>
```

 

---
 
## Funnels  
    
### Afspraak maken - funnel
#### This guide is used to setup the tracking for the “Afspraak maken” funnel.
![](https://i.imgur.com/nnpAvn3.png)

    
**Funnel**
There are multiple ways of entering the funnel as can be seen below.
![](https://i.imgur.com/Yc28UKF.png)

The funnel is different depending on the appointment type. We define the following steps:

**Already wearing
Fill out zipcode
Store and time selection
Details
Success**

![](https://i.imgur.com/bj5q51m.png)

Already wearing
When the page is loaded, trigger the following: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'funnelStepView',
	'data': {
    	'eventCategory': "User interaction',
    	'eventAction': 'Make appointment - Already wearing',
	    'funnelName': 'Make appointment',
    	'funnelStep': 'Already wearing',    	
        'funnelOrigin': '<see variables table>',
    	'appointmentType': "<See possible values in variables table>',
    	'appointmentCategory': "<See possible values in variables table>"
	
	}
});                    
  
</script>
```
Example:
    ![](https://i.imgur.com/Z3yzBXt.png)

Already Wearing Question Answered
Based on the answer another events with name alreadyWearingQuestionAnswered is pushed to dataLayer with each answer, holding information about the answer:
    ![](https://i.imgur.com/u4I4btB.png)
    ![](https://i.imgur.com/sPrEH5G.png)


  ![](https://i.imgur.com/br8Ptxi.png)


    
    
    
    
    
    
Fill out zipcode
When the page is loaded, trigger the following: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'funnelStepView',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Make appointment - Fill out zipcode',
	    'funnelName': 'Make appointment',
    	'funnelStep': 'Fill out zipcode',
        'funnelOrigin': '<see variables table>',
    	'appointmentType': '<See possible values in variables table>',
    	'appointmentCategory': '<See possible values in variables table>'
	}
});

                   
</script>
```
  Example:
    ![](https://i.imgur.com/FgB24EV.png)

Store and time selection
After the zipcode is filled out and the available stores are shown:
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'funnelStepView',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Make appointment - Store and time selection',
	    'funnelName': 'Make appointment',
    	'funnelStep': 'Store and time selection',
        'funnelOrigin': '<see variables table>',
    	'appointmentType': '<See possible values in variables table>',
    	'appointmentCategory': '<See possible values in variables table>'
	}
});

                   
</script>
```
 Example:
    ![](https://i.imgur.com/vb0A26C.png)

Viewed store block
Wjen the store block is displayed the information in the dataLayer has to be filled like this with event push storeBlockView:
![](https://i.imgur.com/isVc7pH.png)
![](https://i.imgur.com/S93fXlJ.jpg)

    
    

    
Details
When the page is loaded after the user chooses a store and time:

``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	"event": "funnelStepView",
	"data": {
    	"eventCategory": "User interaction",
    	"eventAction": "Make appointment - Details",
	"funnelName": "Make appointment",
    	"funnelStep": "Details",
      "funnelOrigin": "<see variables table>",
    	"appointmentType": "<See possible values in variables table>",
    	"appointmentCategory": "<See possible values in variables table>"
	}
});
    
</script>
```
    
Success
When the user successfully submits the appointment: 

``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'generate_lead',
     'data': {
     'eventCategory': 'User interaction',
     'eventAction': 'Make appointment - Success',
     'funnelName': 'Make appointment',
     'funnelStep': 'Success',
     'funnelOrigin': '<see variables table>',
     'appointmentType': '<See possible values in variables table>',
     'appointmentCategory': '<See possible values in variables table>',
     'appointmentID': "<Id of the appointment>'
}
});               
    
</script>
```
   Example:
![](https://i.imgur.com/5mTrvqi.png)

---
    
    
### Herhaalbestellingen - funnel
#### This guide is used to setup the tracking for the “Herhaalbestellingen” funnel.
![](https://i.imgur.com/j03WtTj.png)

Funnel
The funnel consists of two steps:

**Repeat order overview
Success**


Note: The funnelOrigin variable will be calculated in GTM and is therefore not mentioned in the code examples below.


``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'begin_checkout',
     'data': {
     'eventCategory': 'User interaction',
     'eventAction': 'Repeat checkout - Overview',
     'funnelName': 'Repeat checkout",
     'funnelStep': 'Overview',
     'isRepeatOrder': '1',
     'items': :[{
        	...lineItemProductData
    	}]
	}
});
     
</script>
```
    
    
Success

``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'purchase',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Repeat checkout - Purchase',
   	'funnelName': 'Repeat checkout',
    	'funnelStep': "Success',
   	 'isRepeatOrder':'1',
    	'eventValue': '35.43', //Transaction revenue
    	'purchase': {
        	'id": 'T12345',
        	'tax': 4.90,
        	'shipping': 5.99,
        	'couponCode':'',
        	'paymentMethod':',
        	'shippingMethod':'
    	},
    	'items': [{
            	...lineItemProductData
        	}
    	]
	}
});
     
</script>
```
    
---
    
    
### Zichtzendingen - funnel
#### This guide is used to setup the tracking for the “Zichtzendingen” funnel.
![](https://i.imgur.com/Rx3Lc0Z.png)
    
    
**Funnel**
The funnel has the following steps

**Personal information**
**Store and time selection**
**Success**

    
    

    
Personal information
    
When the page is loaded, trigger the following:

``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'funnelStepView',
     'data': {
     'eventCategory': 'User interaction',
     'eventAction': 'Zichtzending - Personal information',
     'funnelName': 'Zichtzending',
     'funnelStep': 'Personal information'
     
	}
});
     
</script>
```
Store and time selection
    
After the zipcode is filled out and the available stores are shown:

``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'funnelStepView',
     'data': {
     'eventCategory': 'User interaction',
     'eventAction': 'Zichtzending - Store and time selection',
     'funnelName': 'Zichtzending',
     'funnelStep': 'Store and time selection'
     
	}
});
     
</script>
```

Success
    
When the user successfully submits the appointment:

``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'generate_lead',
     'data': {
     'eventCategory': 'User interaction',
     'eventAction': 'Zichtzending - Success',
     'funnelName': 'Success',
     'tryOnId': '<Id of the try on>',
         "items": [{

                  ...lineItemProductData
}
]
     
	}
});
     
</script>
```
    


    
---
    
    
### Recommender - funnel 
#### This guide is used to set up the tracking for the “Recommender” funnel.
Funnel
The funnel contains the following steps.
1. Landing page
2. Instructions - Light
3. Instructions - Neutral
4. Instructions - On screen
5. Picture
6. Picture result page
7. Fitting room
8. Glasses selection
9. Sight order OR Direct order

    
Parts of the funnel are depicted within an iFrame. The iFrame is managed by PTTRNS.
Therefore, PTTRNS should export data on the steps 2 up to and including 6 to Hans Anders.
Special events within the funnel
Visitors take a picture of their face at step 5 of the funnel. The visitor receives an error message
if the picture was taken incorrectly. We want to know how much this happens. Therefore, we
have the following event:
 
**1. incorrectPicture**
Information on this special event should be exported by PTTRNS to Hans Anders.
    
**Funnel steps managed by Hans Anders**
    
Landing page
When the page is loaded, trigger the following:
    
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'funnelStepView,',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Glasses recommender - Introduction',
   	    'funnelName':'Glasses recommender',
   	    'funnelStep':'Introduction'
	}
});


     
</script>
```
    
Fitting room
The following code should be triggered when the user enters the fitting room with the predefined
set of recommended glasses:
    
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'funnelStepView,',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Glasses recommender - Fitting room',
   	    'funnelName':'Glasses recommender',
   	    'funnelStep':'Fitting room'
	}
});
    
</script>
```
    
Glasses selection
The following code should be triggered if the user reaches the screen with the glasses selection:
    
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'funnelStepView,',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'Glasses recommender - Glasses selection',
   	    'funnelName':'Glasses recommender',
   	    'funnelStep':'Glasses selection'
	}
});
    
</script>
```
 
---
    
    

    
**Error handling**
    
If a user encounters an system error, for example:
![](https://i.imgur.com/7qkmdOm.png)

Then we should track this information the following way:
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
	'event': 'systemError',
	'data': {
    	'eventCategory': 'User interaction',
    	'eventAction': 'System error',
    	'funnelName': 'Product checkout',
    	'funnelStep': "Success',
   	    'isRepeatOrder':'0',
    	'errorMessage': 'Request failed with status code 500'
});
     
</script>
```
  
    
---
## Other events
    
    

    
    


### bannerClick
If a visitor clicks on banner blocks on the end of pages containing this URL https://www.hansanders.nl/acties, then the following dataLayer has to be filled: 

``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
   'event' : 'bannerClick',
     'index': "1"               //Position of the banner:1,2,3,...
    
});               
    
</script>
```
![](https://i.imgur.com/ktcu8N8.png)





### filter
When a visitor performs all possible actions, dataLayer event is pushed with information on each action, and action type (option, close, open, sort, category, select, submit): 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'gtm.trackEvent',
  'eventCategory': 'filter', 
  'eventAction': 'option',                  //either ooption, close, open, sort, category, select, submit
  'eventLabel': 'select - Zonnebrillen'    //Option selected
    or
  'eventLabel': 'open - Geslacht'          //When filter category is expanded
</script>
```

![](https://i.imgur.com/XAiaxFE.jpg)


### login
When a visitor fills e-mail and pasword for login: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'gtm.trackEvent',
  'eventCategory': 'login', 
  'eventAction': 'field',                
  'eventLabel': 'LoginData.EmailAddress'    //LoginData.EmailAddress or LoginData.Password
 
</script>
```
![](https://i.imgur.com/beyemG8.png)


***By entering e-mail adress and continuing in the pw field one event is pushed with LoginData.EmailAddress as Label, and by entering pw and continuing successfully on the next page by clicking on the Versturen button second event is pushed with Label LoginData.Password**

### Lenzen PDP interactie
All the Shop buttons on the Start and content pages. Also the sticky box on the lower right side and the box under the text in the main conent colomn: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'gtm.trackEvent',
  'eventCategory': 'Lenzen PDP interactie', 
  'eventAction': 'Kies Plan',                
  'eventLabel': 'contract'    //contract or order (when first selection is selected and by clicking on red button Label should be order, and if second button is selected than it should be contract)
 
</script>
```
![](https://i.imgur.com/ktiHJyz.png)
    
### tools
When a visitor makes selection in the three boxes on this page https://www.hansanders.nl/service/zorgverzekering/: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'gtm.trackEvent',
  'eventCategory': 'tools', 
  'eventAction': 'Kies je zorgverzekering' // Selecteer je pakket, Kies je productgroep, Kies je zorgverzekering               
  
</script>
```
![](https://i.imgur.com/piDrkzX.png)
    
### more_information
When a visitor makes selection in the three boxes on this page https://www.hansanders.nl/service/zorgverzekering/: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'gtm.trackEvent',
  'eventCategory': 'more_information', 
  'eventAction': 'product_specification', 
  'eventLabel': 'open'                      //open or close
  
</script>
```
![](https://i.imgur.com/XFliUmR.png)
    
### interaction - specs
When a visitor clicks on view more button under product specification on PDP pages, then the following dataLayer needs to be pushed: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'gtm.trackEvent',
  'eventCategory': 'interaction', 
  'eventAction': 'specs', 
  'eventLabel': 'open'                     
  
</script>
```
![](https://i.imgur.com/th2bxbl.png)
    
### interaction - load more
When a visitor clicks on a load more button on blog pages, then the following dataLayer needs to be pushed: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'gtm.trackEvent',
  'eventCategory': 'interaction', 
  'eventAction': 'load more', 
  'eventLabel': 'blogs'                     
  
</script>
```
![](https://i.imgur.com/GlHCWKk.jpg)

### Form error message
When a visitor is filling  fields in all forms on the website and a error message pops up for some of the fields: 
``` javascript
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({  
  'event': 'Form error message',
  'eventCategory': 'form', 
  'eventAction': '	field', 
  'eventLabel': see list below                    
  
</script>
```
![](https://i.imgur.com/QtVQ6fw.png)
![](https://i.imgur.com/FcLeZTu.png)









## For questions
:::info
**For all the questions regarding the measurement plan please reach out to:** 
Angela Argirovska - angela.argirovska@deptagency.com
