---
title: Google Tag Manager - iOS
description: Leverage our native integration to send Google Tag Manager events to Contentsquare, with the CSQ iOS SDK
lastUpdated: 23 October 2025
source_url:
  html: https://docs.contentsquare.com/en/csq-sdk-ios/experience-analytics/google-tag-manager/
  md: https://docs.contentsquare.com/en/csq-sdk-ios/experience-analytics/google-tag-manager/index.md
---

If you are using Firebase to track events such as screenviews or transactions, you can trigger these events for Contentsquare with minimal effort, thanks to Google Tag Manager.

## Prerequisite

If you are following this Google Tag Manager integration process, you should already have followed the Google Tag Manager + Firebase setup as described in [Google's Tag Manager + Firebase: Getting Started ↗](https://developers.google.com/tag-manager/ios/)

You also need to integrate the CSQ SDK [see section: Add Contentsquare to your app](../#install-the-sdk).

## Screenview events

This section covers how to trigger a Contentsquare screenview event for every Firebase screenview event. Firebase allows you to [log screenviews automatically or manually ↗](https://firebase.google.com/docs/analytics/screenviews) for an exhaustive coverage of your app screens.

### Variables

Contentsquare screenview events require a `name` parameter.

Firebase has 2 ways to track screens:

#### 1. Variable for automatically tracked screens

Firebase’s `screen_view` events have an `_sc` parameter (for screen class) which we can use as parameter for screens that are **automatically tracked**.

We will create a variable called **Automatic Screenview Name** with:

* The **Variable Type** set to **Event Parameter**
* The **Event Type** set to **Custom Parameter**
* The **Event Parameter Key** set manually to `_sc`

![](https://docs.contentsquare.com/_astro/gtm-screenview-variable-auto.DBb_tfSp_Z1jB9ik.webp)

#### 2. Variable for manually tracked screens

Firebase’s `screen_view` events have a `_sn` parameter (for screen name) which we can use as parameter for screens that are **manually tracked**.

We will create a variable called **Manual Screenview Name** with:

* The **Variable Type** set to **Event Parameter**
* The **Event Type** set to **Custom Parameter**
* The **Event Parameter Key** set manually to `_sn`

![](https://docs.contentsquare.com/_astro/gtm-screenview-variable-manual.3rST-eEh_FlfI9.webp)

We can also create variables for our own custom parameters, for example, we can send a `screen_view` event like this:

```swift
Analytics.logEvent(AnalyticsEventScreenView, parameters: [
    AnalyticsParameterScreenName: "MyScreenName",
    "is_user_logged_in": "true"
])
```

and create a variable called **Is User Logged In** with:

* The **Variable Type** set to **Event Parameter**
* The **Event Type** set to **Custom Parameter**
* The **Event Parameter Key** set manually to `is_user_logged_in`

Check out [Configure variables in Tag Manager ↗](https://developers.google.com/tag-platform/tag-manager/ios/v5#configure_variables_in_tag_manager) for more information.

### Screenview trigger

We will need to tell Google Tag Manager when to send a Contentsquare screenview, and for that we need to create a **Trigger**. Firebase sends screenviews as events of name `screen_view`, so we need to create a trigger for that event.

* Name your trigger `Screenview Trigger`
* **Trigger Type** should be set to **Custom**
* Trigger should fire on **Some Events**
* For the Event, the **Event Name** should be **equal** to `screen_view`

![](https://docs.contentsquare.com/_astro/gtm-screenview-trigger.CCYQtsTt_Z121dEM.webp)

### Create the custom function Tag

In Google Tag Manager, a **Tag** is what configures what happens when some trigger is activated. It will be automatically linked to a custom class which we will create in a later step.

The **Tag Type** should be a **Function Call**. You will also need to fill in the **Class Name** field with a class name of your liking, typically related to what the tag is about (here we chose `ContentsquareScreenviewTag`), which you will re-use later.

![](https://docs.contentsquare.com/_astro/gtm-screenview-tag.B-OiT2Pu_2fX8B1.webp)

### Adding the trigger and the variables to the Tag

Edit the `ContentsquareScreenviewTag` Tag:

Tip

Type `{{` or click `+` to make sure you are referencing existing GTM variables.

* Add an argument with the key `auto_screen_name` and the variable **`{{Automatic Screenview Name}}`** as the value
* Add an argument with the key `manual_screen_name` and the variables **`{{Manual Screenview Name}} | {{Is User Logged In}}`** or **`{{Manual Screenview Name}}`** as the value
* Add **Contentsquare Screenview Trigger** as the Tag's trigger

It should look like this now:

![](https://docs.contentsquare.com/_astro/gtm-screenview-tag-final.DYwu9H6Q_Z1O7OT9.webp)

### Create the custom function Tag class

In your app code, create a class of the same name as the `Class Name` you configured in the GTM interface, for example `ContentsquareScreenviewTag`. This is how GTM connects the configuration and the actual class to trigger. This class is used to call the Contentsquare screenview tracking function as follows:

* Swift

  ```swift
  @objc(ContentsquareScreenviewTag)
  final class ContentsquareScreenviewTag: NSObject, TAGCustomFunction {
      @objc func execute(withParameters parameters: [AnyHashable : Any]!) -> NSObject! {
          let autoScreenName = parameters[AnyHashable("auto_screen_name")] as? String
          let manualScreenName = parameters[AnyHashable("manual_screen_name")] as? String
          let screenName = manualScreenName ?? autoScreenName ?? "No screen name!"
          CSQ.trackScreenview(screenViewWithName: screenName)
          return nil
    }
  }
  ```

* Objective-C

  ```objective-c
  @implementation ContentsquareScreenviewTag <TAGCustomFunction>


  - (NSObject*)executeWithParameters:(NSDictionary*)parameters {
      NSString *autoScreenName = [parameters objectForKey:@"auto_screen_name"];
      NSString *manualScreenName = [parameters objectForKey:@"manual_screen_name"];
      NSString *screenName = manualScreenName ? : (autoScreenName ? : @"No screen name!");
      [Contentsquare sendWithScreenViewWithName:screenName];
      return nil;
      }


  @end
  ```

Now, every time Firebase sends a screenview event, Contentsquare will send one as well.

## Screenview events with Custom Variables

Custom Variables

Custom variables are additional information on the page, the user or the session, sent with screenviews.\
For more information about custom variables, see [Track Custom Variables](../track-custom-variables/).

It is possible to send custom variables along with the screenview events.\
To do so:

1. Follow **Use Google Tag Manager** > [Screenview events](#screenview-events)

2. Add extra arguments to the `ContentsquareScreenviewTag` Tag as follows:

   * *Key:* the index of the custom variable
   * *Value:* a string that will contain the custom variable name and value such as `CVAR_NAME : {{Event Name}}`

Note

The value of the custom variable is composed of a name and a value: `NAME : VALUE` concatenated into a single string and separated by `:`.

It should look like this: ![](https://docs.contentsquare.com/_astro/gtm-custom-variables-function-call.CAxBUphe_Z1zCwzY.webp)

For Custom Variables

You are free to implement your own logic for filling key and value in GTM, but the application side must be able to receive and extract for each custom variable: 1. An index 1. A name 1. A value

In the code of your application, edit the code of your class to handle the added custom variables:

* Swift

  ```swift
  @objc(ContentsquareScreenviewTag)
  final class ContentsquareScreenviewTag: NSObject, TAGCustomFunction {
    @objc func execute(withParameters parameters: [AnyHashable : Any]!) -> NSObject! {
      let autoScreenName = parameters[AnyHashable("auto_screen_name")] as? String
      let manualScreenName = parameters[AnyHashable("manual_screen_name")] as? String
      let screenName = manualScreenName ?? autoScreenName ?? "No screen name!"
      var cvars = [CustomVar]()
      for (gTagKey, gTagValue) in parameters {


          guard let gTagKey = gTagKey as? String,
                  let cvarIndex = UInt32(gTagKey),
                  let gTagValue = gTagValue as? String else { continue }


          let cvarKeyValue = gTagValue.components(separatedBy: ":")
          if cvarKeyValue.count == 2 {
              let name = cvarKeyValue[0].trimmingCharacters(in: .whitespaces)
              let value = cvarKeyValue[1].trimmingCharacters(in: .whitespaces)
              let cvar = CustomVar(index: cvarIndex, name: name, value: value)
              cvars.append(cvar)
          }
      }
      CSQ.trackScreenview(screenViewWithName: screenName, cvars: [cvars])
      return nil
    }
  }
  ```

* Objective-C

  ```objective-c
  @implementation ContentsquareScreenviewTag<TAGCustomFunction>


  - (NSObject*)executeWithParameters:(NSDictionary*)parameters {
      NSString *autoScreenName = parameters[@"auto_screen_name"];
      NSString *manualScreenName = parameters[@"manual_screen_name"];
      NSString *screenName = manualScreenName ?: autoScreenName ?: @"No screen name!";


      NSMutableArray *cvars = [NSMutableArray array];
      for (NSString *gTagKey in parameters) {


          NSUInteger cvarIndex = [gTagKey integerValue];
          NSString *gTagValue = parameters[gTagKey];
          NSArray *cvarKeyValue = [gTagValue componentsSeparatedByString:@":"];


          if (cvarKeyValue.count == 2) {
              NSString *name = [cvarKeyValue[0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
              NSString *value = [cvarKeyValue[1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
              CustomVar *cvar = [[CustomVar alloc] initWithIndex:cvarIndex name:name value:value];
              [cvars addObject:cvar];
          }
      }


      [CSQ sendScreenViewWithName:screenName cvars:cvars];
      return nil;
  }
  @end
  ```

With this code, the custom variables will be sent by Contentsquare automatically along with the screenview.

## Transaction events

A Contentsquare transaction event can also be triggered for every Firebase `ecommerce_purchase` event (See Firebase [Objective-C ↗](https://firebase.google.com/docs/reference/ios/firebaseanalytics/api/reference/Constants#/c:FIREventNames.h@kFIREventPurchase)/[Swift ↗](https://firebase.google.com/docs/reference/swift/firebaseanalytics/api/reference/Constants#analyticseventpurchase) documentation). To do so, you will need to follow the setup described below.

### Variables

We have to create at least two variables in order to be able to build a transaction event: Value and Currency. Optionally, it is also possible to pass a transaction identifier, meaning you would need to create an additional variable in order to be able to use it.

#### Value (mandatory)

![](https://docs.contentsquare.com/_astro/gtm-transaction-variable-value.hFaSreMy_2kG0Vp.webp)

#### Currency (mandatory)

![](https://docs.contentsquare.com/_astro/gtm-transaction-variable-currency.B-sVY9MZ_2eM5hG.webp)

#### Transaction ID (optional)

![](https://docs.contentsquare.com/_astro/gtm-transaction-variable-transactionid.DJyRmNTH_Z1tJluh.webp)

### Trigger

Create the following custom trigger.

![](https://docs.contentsquare.com/_astro/gtm-transaction-trigger.CLRsqo_K_ZbqLL0.webp)

### Tag

Create a **Function call** Tag called `ContentsquareTransactionTag`, pass the two to three variables created earlier as arguments (skip the `id` line if you do not want to use it) and set its trigger to the one you just created.

![](https://docs.contentsquare.com/_astro/gtm-transaction-tag.CwmbGDS__Z26zgDp.webp)

### Implementing the function call

We need to create a `ContentsquareTransactionTag` class, and have it adhere to the `TAGCustomFunction` protocol to link it to the Google Tag Manager custom Tag of the same name.

Take good note that in order to be able to create and send a Contentsquare Transaction successfully, when you create a Firebase purchase event you will have to at least pass values for `kFIRParameterValue` and `kFIRParameterCurrency`, and can optionally pass a value for `kFIRParameterTransactionID`, when you create a Firebase purchase event.

* Swift

  ```swift
  @objc(ContentsquareTransactionTag)
  final class ContentsquareTransactionTag: NSObject, TAGCustomFunction {


      @objc func execute(withParameters parameters: [AnyHashable : Any]!) -> NSObject! {
          if let currency = parameters[AnyHashable("currency")] as? String,
              let value = parameters[AnyHashable("value")] as? Float {
              let identifier = parameters[AnyHashable("id")] as? String
              CSQ.send(transaction: CustomerTransaction.init(id: identifier, value: value, currency: currency))
          }
          return nil
      }
  }
  ```

* Objective-C

  ```objective-c
  @implementation ContentsquareTransactionTag <TAGCustomFunction>


  - (NSObject*)executeWithParameters:(NSDictionary*)parameters {
      NSString *identifier = [parameters objectForKey:@"transaction_id"];
      NSNumber *value = [parameters objectForKey:@"value"];
      NSString * currency = [parameters objectForKey:@"currency"];
      if (currency && value) {
          [CSQ sendWithTransaction:[[CustomerTransaction alloc]     initWithId:identifier value:[value floatValue] stringCurrency:currency]];
      }
      return nil;
  }


  @end
  ```

Now, every time Firebase sends an `ecommerce_purchase` event, Contentsquare will send one as well.

## Dynamic variable events

We can send values from any Firebase event as a Contentsquare dynamic variable:

```swift
Analytics.logEvent("addToCart", parameters: [
    "product_count": 12,
    "product_name": "ProductA"
])
```

### Variables

The `addToCart` event has parameters `product_count`, `product_name`, we will create variables called **Product Count** and **Product Name** with:

* The **Variable Type** set to **Event Parameter**
* The **Event Type** set to **Custom Parameter**
* The **Event Parameter Key** set manually to `product_count`/`product_name`

Check out [Configure variables in Tag Manager ↗](https://developers.google.com/tag-platform/tag-manager/ios/v5#configure_variables_in_tag_manager) for more information.

### Triggers

We need to create a **Trigger** to tell Google Tag Manager when to send a Contentsquare dynamic variable, so we will create one for the event `addToCart`.

* Name your trigger `AddToCartTrigger`
* **Trigger Type** should be set to **Custom**
* Trigger should fire on **Some Events**
* For the Event, the **Event Name** should be **equal** to `addToCart`

### Create the custom function Tag

We need to create a function tag **AddToCartDynamicVar**

* The **Tag Type** set to **Function Call**
* The **Class Name** set to **DynamicVarTag** (we'll create this class later)
* Add two arguments, `Key: cs_dynamic_var_key, Value: Product`, `Key: cs_dynamic_var_value, Value: {{Product Name}}: {{Product Count}}`
* The **Triggering** set to **AddToCartTrigger**

It should look like this now:

![](https://docs.contentsquare.com/_astro/gtm-dynamic-var-tag.qNpuQBfo_IjkRe.webp)

### Create the custom function Tag class

In your app code, create a class named `DynamicVarTag`, assuming you used the name we suggested when creating the Tag in the GTM interface. If you named it otherwise, make sure to use the same name here, as it is how GTM connects the configuration and the actual class to trigger. We will use this class to call the Contentsquare dynamic variable function as follows.

```swift
import GoogleTagManager
import ContentsquareSDK


@objc(DynamicVarTag)
final class DynamicVarTag: NSObject, TAGCustomFunction {
    @objc func execute(withParameters parameters: [AnyHashable : Any]!) -> NSObject! {
        guard let dynamicVarKey = parameters["cs_dynamic_var_key"] as? String else {
            return nil
        }
        let dynamicVarValue = parameters["cs_dynamic_var_value"]


        if let dynamicVarStringValue = dynamicVarValue as? String {
            let dynamicVarString = DynamicVar(key: dynamicVarKey, value: dynamicVarStringValue)
            CSQ.trackScreenview(dynamicVar: dynamicVarString)
        } else if let dynamicVarIntValue = dynamicVarValue as? UInt32 {
            let dynamicVarInt = DynamicVar(key: dynamicVarKey, value: dynamicVarIntValue)
            CSQ.trackScreenview(dynamicVar: dynamicVarInt)
        }
        return nil
    }
}
```

Now, every time Firebase sends an `addToCart` event, Contentsquare will send a dynamic variable `DynamicVar(key: "Product", value: "ProductA: 12")`.

Note

To create another tag for a dynamic variable, you can use the `DynamicVarTag` class again.
