---
updatedAt: 2026-09-18T09:36:36.000Z
agentTools:
  projectIndex: https://mcm-docs.moloco.com/llms.txt
---

# Google Tag Manager integration guide

# What is Google Tag Manager (GTM)

Google Tag Manager (GTM) is a \*free tool provided by Google that allows users to manage and deploy marketing and analytics tags (snippets of code) on their website or mobile app without needing to modify the underlying codebase. It simplifies the process of tracking user interactions, such as page views, clicks, and conversions, by enabling marketers and analysts to add and update tags through a web-based interface rather than relying on developers.

GTM helps streamline the implementation of third-party tools like Google Analytics, Facebook Pixel, and various ad platforms. It supports both client-side and server-side tagging, giving businesses flexibility in how they manage tracking across their digital properties. This tool enhances efficiency, reduces the risk of code errors, and improves the overall speed of deploying and updating tracking mechanisms.

\*While use of Google Tag Manager by itself is free, when using a server-side setup, hosting and infrastructure fees such as hosting using Google Cloud Platform (GCP) will be incurred.

# Why Moloco recommends using GTM Server-side

Google Tag Manager can operate server-side. It means all the data collection and forwarding can be done server-side, as opposed to client-side by default.

Moloco recommends the use of GTM server-side for the following 3 reasons:

* **Reduce load on a page**: instead of loading and running Javascript snippets to forward events to Moloco from client side, those can be offloaded server-side, reducing page load time.
* **Reduce impact of ad blockers**: with server-side tagging, you can create a custom 1st party subdomain to which you can send the user event data (e.g., analytics.yourdomain.com or yourdomain.com/analytics) avoiding any potential ad blockers that would block HTTP request to non-first party domains.
* **Secure MCM API key**: Moloco Commerce Media (MCM) APIs are called using an API key ([read here](https://mcm-docs.moloco.com/docs/api-and-sso-credential-management) for generating one for your platform). Calling MCM APIs from server-side containers will prevent exposing the API key publicly, avoiding any of the risks described [here](https://mcm-docs.moloco.com/docs/event-integration-trade-offs#disadvantages-of-choosing-client-to-server-integration).

For those reasons, we recommend sending user events data to MCM from a server-side GTM container. Note that when choosing to send event data to Moloco servers using a server-side GTM container setup, a client-side Google Tag Manager is still necessary. Before viewing the rest of the below guide, first refer to <Anchor target="_blank" href="https://developers.google.com/tag-platform/tag-manager/server-side/overview">this</Anchor> official guide from Google for setting up a server-side Google Tag Manager container, and then <Anchor target="_blank" href="https://developers.google.com/tag-platform/tag-manager/server-side/send-data">this</Anchor> official guide for how to send data from your website to the server-side Google Tag Manager.

# Recording user events using Google Tag Manager

Tag Manager provides a way to manage and test multiple tags without many server-side code changes to your site.
Some decisions you make during setup depend on whether you are using Google Analytics and Google Analytics Ecommerce. Google Analytics Ecommerce can be implemented using Google Analytics 4 or Enhanced Ecommerce.
Neither Google Analytics nor Google Analytics Ecommerce is required; if you don't use them, you can manually populate your site's data layer code after creating the tag.

Google Analytics Ecommerce is an additional configuration for Google Analytics that passes product titles, IDs, prices, transaction details, and other structured ecommerce data to Google Analytics. MCM can leverage the Google Analytics Ecommerce data layer, so if you have that set up already, configuration can be easier. If you don't have Google Analytics Ecommerce configured for Google Analytics but want to use it, see more details and setup instructions in the [GA4 developer guide](https://developers.google.com/analytics/devguides/collection/ga4/ecommerce?client_type=gtm)

Use this one-time procedure to set up a Moloco Commerce Media tag in Tag Manager for recording user events.

# Standard GA4 ecommerce event & MCM mapping

This table describes the mapping of standard GA4 ecommerce events with [MCM event types](https://mcm-docs.moloco.com/docs/user-event-data-specifications).

| GA4 ecommerce Event Name | MCM Event Name    | Notes                                           |
| :----------------------- | :---------------- | :---------------------------------------------- |
| add\_to\_cart            | ADD\_TO\_CART     |                                                 |
| page\_view               | PAGE\_VIEW        |                                                 |
| view\_item               | ITEM\_PAGE\_VIEW  |                                                 |
| page\_view               | HOME              | Only triggers HOME event when page\_path == “/” |
| purchase                 | PURCHASE          |                                                 |
| search                   | SEARCH            |                                                 |
| add\_to\_wishlist        | ADD\_TO\_WISHLIST |                                                 |

<Callout icon="🚧" theme="warn">
  ### Important to note

  MCM expects to receive a PAGE_VIEW event when a user navigates to **any page that is not the homepage or PDP page**.

  For homepage and PDP, you should respectively trigger **HOME and ITEM_PAGE_VIEW** events.

  When a user lands on your website from an external source, you should trigger **the appropriate page view event (either HOME or ITEM_PAGE_VIEW or PAGE_VIEW)**.
</Callout>

# GTM x MCM integration overview

This is the high level solution architecture:

<Image src="https://files.readme.io/5cef5cd502dcb006ba0db8834de100a540ecadb507d10d0856f8f1194a241706-SCR-20250513-kdwk.png" align="center" />

The diagram shows 3 important steps:

1. User event collection on the website or mobile app using the GTM client-side container.  Those tags are being forwarded to the GTM server-side container.
2. A GTM server-side server has been [deployed](https://developers.google.com/tag-platform/tag-manager/server-side/cloud-run-setup-guide) on Google Cloud. GTM offers a 1-click deployment  but the server (Docker container) can be deployed manually on GCP or any other Cloud provider.
3. User events are forwarded to MCM using server-side tags. MCM User Event API Template (provided by Moloco) can be imported to facilitate the event forwarding.

# GTM server-side deployment

Using the auto-provisioning (1-click deployment), you can deploy a server-side tagging server on Google Cloud. Please follow the instructions available [here](https://developers.google.com/tag-platform/tag-manager/server-side/cloud-run-setup-guide).

Things to be aware of regarding the tagging server:

* By default, the tagging server will be deployed in the US region (us-central1). If you want to deploy the server in a different region, a manual deployment is recommended ([instructions](https://developers.google.com/tag-platform/tag-manager/server-side/cloud-run-setup-guide?provisioning=manual#provisioning)).
* Running a server in the Cloud **generates GCP fees**. Google provides a simple [pricing calculator](https://developers.google.com/tag-platform/tag-manager/server-side/cloud-run-setup-guide#cloud_run_cost) based on the number of events collected per month. Expect 100 USD/month for 10M events.
* As the server-side container will handle millions of requests, we recommend following [Google instructions](https://developers.google.com/tag-platform/tag-manager/server-side/cloud-run-setup-guide?provisioning=automatic#optional_disable_logging) to disable unneeded logging to avoid generating extra fees.
* The tagging server is updated by Google over time so updating to the latest version will also be required as part of the on-going server operation. You can find server-side tagging server release notes [here](https://developers.google.com/tag-platform/tag-manager/server-side/release-notes#2.4.0).
* If you want to host server-side tagging in the same [first-party context](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#tracking_and_privacy) as your website, we recommend configuring a custom domain for your GTM server ([instructions](https://developers.google.com/tag-platform/tag-manager/server-side/custom-domain?option=same-origin)). Same-origin serving is a best practice that lets you leverage the security and durability benefits of server-set cookies.
* GTM server-side doesn’t offer a retry mechanism baked into it so if, for some unexpected reasons, MCM Event API is temporarily unavailable, events will be lost. To mitigate this risk, it is possible to save events to BQ to keep a backup of events or to send failed events into an external queue service (like Cloud PubSub or Cloud Tasks) and build your own retry worker (using Cloud Run on Cloud Functions). Please reach out to your Moloco representative to get advice on the best solution for your needs.

# Server-side GTM container config setup

The section below describes the different configurations required for forwarding user events collected on GTM client side to MCM User Event API.

## Community Template Gallery

The official **MCM User Event API Server-side templates** is available in the Community Template Gallery, and contains a script to send API request to MCM Event API with required body contents per event\_type. If you are not able to find the template in the Community Template Gallery, you may also choose to manually import the template by downloading it from <Anchor target="_blank" href="https://github.com/moloco-mcm/mcm-gtm-template">this</Anchor> Github repository and following the official guide <Anchor target="_blank" href="https://developers.google.com/tag-platform/tag-manager/templates">here</Anchor>.

When you import the provided tpl file, the following configuration will be added on your template.

<Image src="https://files.readme.io/6c7daa528e98cc6dd062c41038da989d278d98ab1008f58ec48d3b02dfe6334c-SCR-20250613-jeuu.png" align="center" />

Follow these steps to add the **MCM User Event API** template to your workspace:

1. In your GTM server-side workspace, navigate to **Template**
2. Under **Tag Template**, click **Search Gallery**
3. In the search field, type "**Moloco**" and you will find the **MCM User Event API template**
4. Click on **Add to workspace**, then click again on **Add**

When the template has been successfully added, the following fields will be populated:

| Field name     | Description                 |
| :------------- | :-------------------------- |
| api\_key       | MCM User Event API key      |
| api\_url       | MCM User Event API endpoint |
| id             | Event ID                    |
| event\_type    | Event type                  |
| channel\_type  | Channel type (APP/SITE)     |
| user\_id       | User ID                     |
| page\_id       | Page ID                     |
| items          | Items                       |
| currency       | Currency                    |
| value          | Amount                      |
| search\_term   | Search keyword              |
| device         | Device info                 |
| persistent\_id | Persistent ID               |
| os             | OS                          |

## Variables

The following variables are required to parse the event contents and deliver those through Tag (MCM user event API).

| Variable name  | Type       | Value / Key Path / Format                  |
| :------------- | :--------- | :----------------------------------------- |
| api\_key       | Constant   | <<Replace by your MCM Event API key>>      |
| api\_url       | Constant   | <<Replace by your MCM Event API endpoint>> |
| currency       | Event Data | currency                                   |
| persistent\_id | Event Data | persistent\_id                             |
| os             | Event Data | client\_hints.platform                     |
| event\_id      | Event Data | event\_id                                  |
| items          | Event Data | items                                      |
| page\_id       | Event Data | page\_id                                   |
| event\_type    | Event Name | Change Case to Uppercase                   |
| search\_term   | Event Data | search\_term                               |
| user\_id       | Event Data | user\_id                                   |
| value          | Event Data | value                                      |
| channel\_type  | Event Data | channel\_type                              |

## Tags & Triggers

The following tags are required to capture GA4 events fired from your site:

### Sending Events to GA4

*(If you do not use GA4 for reporting or analysis, you may skip this section)*

Every time GA4 tags from the GTM web container sends data to the GTM server container, the GA4 client will catch it and make the data available to tags, variables, etc inside of the GTM server container. When that happens, you must create a Google Analytics 4 server tag to send the data further to GA4 servers.

To create the one GA4 tag, go to **Tags > New > Google Analytics: GA4**. This tag will forward all the data from a Google Analytics 4 client. We will not update anything under Event Parameters or User Properties at this time.

<Image src="https://files.readme.io/22497caa7489bdc5043e19e832b493ece62fe73e11e58e2929d7c4819a4eb397-SCR-20250513-mtmr.png" align="center" />

In the **Triggering** section, create a new trigger by clicking on the "+" icon on the top right of the "Choose a trigger" modal window with the following trigger configurations:

* Trigger type: **Custom**
* This trigger fires on: "**Some Events**"
* **\{\{Client Name}} equals ‘GA4’** - If you do not see "\{\{Client Name}}" in the list of selections, select "Choose Built-In Variable..." --> "Client Name"

<Image src="https://files.readme.io/5c85e16167a6a90527585162d7ec8bb2164f7a1ac6207afb6a520715f248c860-SCR-20250513-munr.png" align="center" />

### MCM user event API

By using the ‘**MCM User Event API template**’ imported previously, you can easily create the ‘MCM user event API’ tag to send HTTPS request to Moloco MCM's Event API when the designated event is received.

<Image src="https://files.readme.io/be6152e9f0c79a320eb4b0b975d71efc206b946a866c5d80f3b329ee872c90df-SCR-20250513-mwpk.png" align="center" />

Then you will need to assign the variables previously created to each field.

<Image src="https://files.readme.io/3f9682cbef3d38b1c0c28ba0d7ef9d8c4ac813080020a142367428e8bbe909cd-image-20250903-091255.png" align="center" />

In the **Triggering** section, create a new trigger with the following config:

* Trigger type: **Custom** Event
* Event name: (Use regex matching)
  **^(add\_to\_cart|purchase|add\_to\_wishlist|search|home|page\_view|view\_item)$**
* This trigger fires on: **event\_id does not equal undefined**

**NOTE**: The last setting is needed to avoid GA default event triggering MCM user event Tag

<Image src="https://files.readme.io/738fe00ea1dbdff572e600344f0d874db65e8405b2356f61912a6680e0c19667-SCR-20250513-ncao.png" align="center" />

# Client-side GTM web container config setup

The section below describes the different configurations required for collecting user events on the client side and then forwarding them to the server-side GTM container.

## Variables

For MCM tags to send the needed data to MCM User API, we need to prepare some variables that will be sent with each event.

| Variable name          | Type                                    |
| :--------------------- | :-------------------------------------- |
| search\_term           | URL                                     |
| server\_container\_url | Google Tag: Configuration Settings      |
| event\_id              | Custom Javascript                       |
| channel\_type          | Custom Javascript                       |
| user\_id               | 1st Party Cookie or Data Layer Variable |
| persistent\_id         | 1st Party Cookie or Data Layer Variable |
| common\_fields         | Google Tag: Event Settings              |

### search\_term

If you are already sending a ‘search’ event according to Recommended Events [guide](https://developers.google.com/analytics/devguides/collection/ga4/reference/events?client_type=gtm#search) of Google Analytics, you can retrieve the **search\_term** parameter using a Data Layer variable as shown below.

* Type: Data Layer Variable
* Data Layer Variable Name: search\_term

If you are not currently pushing a search event, you can alternatively [trigger the search event by detecting the page URL](https://www.analyticsmania.com/post/extract-a-query-parameter-with-google-tag-manager/) and [retrieving the search\_term from it](https://www.analyticsmania.com/post/extract-a-query-parameter-with-google-tag-manager/).

If your site has an url format for search page similar to <https://yoursite.com/search?q=my_search_query>, then you can create a new variable as below:

* **Variable Name**: Search\_term
* **Variable Type**: URL
* **Component Type**: Query
* **Query Key**: q

<Image src="https://files.readme.io/a20c1bb7d73ddfd4a423078597719b5edffdaa713eb2d9094f9c2ba18abe0f7e-SCR-20250513-nguy.png" align="center" />

### server\_container\_url

* **Variable Name**: Server\_container\_url
* **Variable Type**: Google Tag:Configuration Settings
* **Config parameter**: server\_container\_url
* **Value**: Your cloud run server url

More detailed information about sending events to server-side container is available [here](https://developers.google.com/tag-platform/tag-manager/server-side/send-data?option=GTM).

### event\_id

* **Variable Name**: Event\_id
* **Variable Type**: Custom JavaScript
* **Custom Javascript**: Script to generate random event ID

`function() {  
 return Math.random().toString(36).substr(2, 10);  
}`

### channel\_type

You may have your own way to recognize which environment your users are in for the session.
In below example, User Agent information determines which environment your user is in.

* **Variable Name**: Channel\_type
* **Variable Type**: Custom JavaScript
* **Custom Javascript**: Script to detect the channel\_type from the user agent information.

`function() {  
 var ua = navigator.userAgent.toLowerCase();  
 if (ua.indexOf("android") > -1 || ua.indexOf("iphone") > -1 || ua.indexOf("ipad") > -1) {  
   return "APP";  
 } else {  
   return "SITE";  
 }  
}`

### user\_id

Please use your own way to retrieve UserID information.
If you store the ID in the 1st party cookie, you can configure the User\_ID variable as below.
Please make sure to use hashed value derived from User ID.

<Image src="https://files.readme.io/bbf4e630e884d54bf123e23813b46c138d88722149697916e5a93a29f942b7cc-SCR-20250515-qcsc.png" align="center" />

### persistent\_id

Please use your own way to retrieve PersistentID information.
If you store the ID in the 1st party cookie, you can configure the Persistent\_ID variable as below.

<Image src="https://files.readme.io/2c5fa03bedd6a7a381b7cc169ac78e6b4fbb168865d807487feeeffaceac4f54-SCR-20250515-ilyy.png" align="center" />

### common\_fields

The following variables are common to all event types, so it’s convenient to config as Event Setting:

* **Variable Type**: Google Tag: Event Settings

| Event Parameter | Value                |
| :-------------- | :------------------- |
| event\_id       | \{\{Event\_ID}}      |
| page\_id        | \{\{Page Path}}      |
| user\_id        | \{\{User\_ID}}       |
| persistent\_id  | \{\{Persistent\_ID}} |
| channel\_type   | \{\{Channel\_type}}  |

## Triggers

The following triggers are required to detect and send MCM user events to GTM server-side.

### View\_item/purchase/add\_to\_cart/add\_to\_wishlist

In order to track all events for MCM except for home, page\_view and search, create the following trigger:

* **Trigger Type**: Custom Event
* **Event name**: ^(add\_to\_cart|purchase|add\_to\_wishlist|view\_item)$
  * **Check** on ‘User regex matching”
* **This trigger fires on**: All Custom Events

<Image src="https://files.readme.io/64f0b6d99d1d132754852cfc097d075addd14d904296f8873a8f93cb89a6fff5-SCR-20250515-pzep.png" align="center" />

### Search

If you are already pushing a ‘search’ event according to Recommended Events [guide](https://developers.google.com/analytics/devguides/collection/ga4/reference/events?client_type=gtm#search) of Google Analytics, You can configure a trigger as below:

* **Trigger Type**: Custom Event
* **Event name**: search
* **This trigger fires on**: some custom event : search

If you are not currently pushing a search event, you can alternatively [trigger the search event by detecting the page ](https://www.analyticsmania.com/post/extract-a-query-parameter-with-google-tag-manager/)URL:

* **Trigger Type**: Page View - Window Loaded (or history change)
* **This trigger fires on**: Some Window Loaded Events
  * \{\{Page Path}} contains ‘/search’ (depending on your site path for search)

<Image src="https://files.readme.io/f4cd03e1d5f486d6af09ebd715bbe7f1b791a4c914b1ad5f61e0974b0cb91b30-SCR-20250515-qakl.png" align="center" />

### Home - window loaded

Home event to be fired when user lands on home page (path : /).

* **Trigger Type**: Page View - Window Loaded
* **This trigger fires on:** Some Window Loaded Events
  * \{\{Page Path}} equals ‘/’

<Image src="https://files.readme.io/dd53ff81f20f5b49774ebd0374aaba326bcfff137ca5c562c22448ea0c4e4dae-SCR-20250515-qazd.png" align="center" />

### Home - history change

This is another trigger of Home event for SPA type of site.

* **Trigger Type**: History Change
* **This trigger fires on**: Some History Changes
  * \{\{Page Path}} equals ‘/’

<Image src="https://files.readme.io/2da4191526d6064587547aa742b4e6eb503395043b9a5e27a374b9e822829b7b-SCR-20250515-qbly.png" align="center" />

### Page\_view - Window Loaded

Pageview triggers on page visit event except for Home and Product Detail page

* **Trigger Type**: Window Loaded
* **This trigger fires on**: Some Window Loaded Events
  * \{\{Page Path}} does NOT equals ‘/’
  * \{\{Page Path}} does NOT contain ‘/product/’ (Config depends on your Product Detail page path)

<Image src="https://files.readme.io/16c6a3da11454bffa2234492a23fa1e85b61ffa52a673af85b6ee78e82b20dad-SCR-20250515-qbwd.png" align="center" />

### Page\_view - History Change

This is another trigger of Page\_view event for SPA type of site

* **Trigger Type**: History Change
* **This trigger fires on**: Some History Changes
  * \{\{Page Path}} does NOT equals ‘/’
  * \{\{Page Path}} does NOT contain ‘/product/’ (Config depends on your Product Detail page path)

<Image src="https://files.readme.io/2a23969d7683c40f64a7447917f7443612d9571c0e1fe8d72d46914169c4fa8d-SCR-20250515-qcec.png" align="center" />

## Tags

The following tags are required to capture MCM user events:

### GA4 connection

To set up a Google tag for server-side processing, you need to add your server container URL to the GA4 tag. In your web container, open the Google Tag responsible for activating Google Analytics 4. Then click Configuration settings > Add parameter and enter “server\_container\_url” as the parameter and your server-side endpoint subdomain as the value.

<Image src="https://files.readme.io/b468371292871dcb7746ba1324eff70b67bf83b75d684aca8279f91ed294ab05-SCR-20250515-kxue.png" align="center" />

### View\_item/purchase/add\_to\_cart/add\_to\_wishlist

Those events are fired by all MCM related triggers except for home, page\_view and search.

* **Tag Type**: Google Analytics:GA4 Event
* **Event Name**: \{\{Event}}
* **Event Parameters**:
  * **Event Setting Variable**: \{\{common\_fields}}
  * **More Settings**
    * Send Ecommerce Data
    * **Data source**: Data Layer
  * **Triggering**
    * **Select the previously create trigger**: view\_item/purchase/add\_to\_cart/add\_to\_wishlist

<Image src="https://files.readme.io/b68d092fd7cc43ee3485d052c9092a399603358a79c2f1a2bc2fad57ff5f801c-SCR-20260325-lrmg.png" align="center" />

### Page\_view

The Page\_view tag handles page\_view event fired by url changes with some conditions.

* **Tag Type**: Google Analytics:GA4 Event
* **Event Name**: page\_view
* **Event Parameters**:
  * **Event Setting Variable**: \{\{common\_fields}}
* **More Settings**
  * Send Ecommerce Data
  * **Data source**: Data Layer
* **Triggering**
  * Page\_view - History change
  * Page\_view - Window loaded

<Image src="https://files.readme.io/524b22ea2d3daa55eb3d3ee5ad3ab45a4f1cdf03cdcbfd0469c0190853ad7dc4-SCR-20260325-lrxn.png" align="center" />

### Home

The Home tag handles home event fired by url changes with some conditions.

* **Tag Type**: Google Analytics:GA4 Event
* **Event Name**: home
* **Event Parameters**:
  * **Event Setting Variable**: \{\{common\_fields}}
* **More Settings**
  * Send Ecommerce Data
  * **Data source**: Data Layer
* **Triggering**
  * Home - history change
  * Home - window loaded

<Image src="https://files.readme.io/a2dad7dc5d09fa755e5f1a364106e7759640e8bd5b14f0cc1b6d961f4de9b0ed-SCR-20260325-lsay.png" align="center" />

### Search

The Search tag handles search event fired by custom event or url changes with some conditions, and additionally delivers \{\{search\_term}} variable along with \{\{common\_fields}}.

* **Tag Type**: Google Analytics:GA4 Event
* **Event Name**: search
* **Event Parameters**:
  * **Event Setting Variable**: \{\{common\_fields}}
  * **Event parameters**:
    * **search\_term**: \{\{search\_term}}
* **More Settings**
  * Send Ecommerce Data
  * **Data source**: Data Layer
* **Triggering**
  * search

<Image src="https://files.readme.io/4296f16f5c6dc60f83690327b9aee99c152f93a2335afe3ea8fe5354451545ed-SCR-20260325-lsfl.png" align="center" />

# Sample HTML script

The following sample HTML page can be used to test sending user events to GTM.

```
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 <title>GTM-MCM Demo Event Page</title>
 <!-- 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','<YOUR_GTM_ID>');
 </script>
 <!-- End Google Tag Manager -->
</head>
<body>
 <!-- Google Tag Manager (noscript) -->
 <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<YOUR_GTM_ID>"
 height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
 <!-- End Google Tag Manager (noscript) -->


 <h1>Hello, Demo event page!</h1>
 <button onclick="handleAddToCartButtonClick({ productId: 'prod-1' })">Add to Cart</button>
 <button onclick="handlePurchaseButtonClick()">Purchase</button>
 <button onclick="handleHomeButtonClick()">Home</button>
 <button onclick="handlePageViewButtonClick()">Page View</button>
 <button onclick="handleAddToWishlistButtonClick()">Add to Wishlist</button>
 <button onclick="handleItemPageViewButtonClick()">Item Page View</button>


 <form id="searchForm">
   <input type="text" id="searchInput" placeholder="Search..." required />
   <button type="submit">Search</button>
 </form>


 <script>
   document.cookie = "persistent_id=id_from_cookie; path=/; max-age=" + (60 * 60 * 24 * 365);
   document.cookie = "user_id=user_id_from_cookie; path=/; max-age=" + (60 * 60 * 24 * 365);


   const product = {
     id: 'test-prod-1',
     title: 'Test Product',
     price: { amount: 449.99, currency: 'USD' }
   };
   const product2 = {
     id: 'test-prod-2',
     title: 'Test Product 2',
     price: { amount: 549.99, currency: 'USD' }
   };
   const channel_type = 'SITE';


   const addFn = ({ item }) => console.log('Item added to cart:', item);


   document.getElementById('searchForm').addEventListener('submit', function(event) {
     event.preventDefault();
     const searchQuery = document.getElementById('searchInput').value;
     window.dataLayer = window.dataLayer || [];
     window.dataLayer.push({
       event: 'search',
       channel_type,
       search_term: searchQuery
     });
     console.log('Search event pushed:', searchQuery);
   });


   const handleAddToCartButtonClick = ({ productId }) => {
     addFn({ item: { productId, quantity: 1 } });
     window.dataLayer.push({
       event: 'add_to_cart',
       channel_type,
       ecommerce: {
         currency: product.price.currency,
         value: product.price.amount,
         items: [
           { item_id: product.id, item_name: product.title, price: product.price.amount, quantity: 1 },
           { item_id: product2.id, item_name: product2.title, price: product2.price.amount, quantity: 1 }
         ]
       }
     });
   };


   const handlePurchaseButtonClick = () => {
     window.dataLayer.push({
       event: 'purchase',
       channel_type,
       ecommerce: {
         currency: product.price.currency,
         value: product.price.amount + product2.price.amount,
         items: [
           { item_id: product.id, item_name: product.title, price: product.price.amount, quantity: 1 },
           { item_id: product2.id, item_name: product2.title, price: product2.price.amount, quantity: 1 }
         ]
       }
     });
   };


   const handleHomeButtonClick = () => {
     history.pushState(null, '', '/');
     renderPageContent();
   };


   const handlePageViewButtonClick = () => {
     history.pushState(null, '', '/page_view');
     renderPageContent();
     window.dataLayer.push({
       event: 'page_view',
       page_type: 'page_view',
       channel_type
     });
   };


   const handleAddToWishlistButtonClick = () => {
     window.dataLayer.push({
       event: 'add_to_wishlist',
       channel_type,
       ecommerce: {
         currency: product.price.currency,
         value: product.price.amount,
         items: [
           { item_id: product.id, item_name: product.title, price: product.price.amount, quantity: 1 },
           { item_id: product2.id, item_name: product2.title, price: product2.price.amount, quantity: 1 }
         ]
       }
     });
   };


   const handleItemPageViewButtonClick = () => {
     window.dataLayer.push({
       event: 'view_item',
       channel_type,
       ecommerce: {
         items: [
           { item_id: product.id, item_name: product.title, price: product.price.amount, quantity: 1 },
           { item_id: product2.id, item_name: product2.title, price: product2.price.amount, quantity: 1 }
         ]
       }
     });
   };


   const renderPageContent = () => {
     const banner = document.getElementById('pageViewBanner') || document.getElementById('homeBanner');
     if (banner) banner.remove();


     const newBanner = document.createElement('div');
     newBanner.style.fontSize = '24px';
     newBanner.style.marginTop = '20px';


     if (location.pathname === '/page_view') {
       newBanner.id = 'pageViewBanner';
       newBanner.textContent = 'This is the Page View Page';
       newBanner.style.color = 'blue';
     } else {
       newBanner.id = 'homeBanner';
       newBanner.textContent = 'This is the Home Page';
       newBanner.style.color = 'green';
     }


     document.body.appendChild(newBanner);
   };


   window.addEventListener('load', renderPageContent);
   window.addEventListener('popstate', renderPageContent);
 </script>
</body>
</html>

```