[Video](https://www.youtube.com/watch?v=qFnohYiJ09U)

The data layer is an object used by Google Tag Manager and gtag.js to pass
information to tags. Events or variables can be passed using the data layer, and
triggers can be set up based on the values of variables.

For example, if you fire a remarketing tag when the value of `purchase_total`
is greater than $100, or based on specific events, such as when a button is
clicked, your data layer can be configured to make that data available to your
tags. The data layer object is structured as JSON. For example:

    {
      event: "checkout_button",
      gtm: {
        uniqueEventId: 2,
        start: 1639524976560,
        scrollThreshold: 90,
        scrollUnits: "percent",
        scrollDirection: "vertical",
        triggers: "1_27"
      },
      value: "120"
    }

Google tags are designed to reference information that is added to the data
layer in an organized and predictable way, rather than by parsing variables,
transaction information, page categories, and other signals scattered
throughout your page. A data layer implementation populated with variables and
associated values will help to ensure that relevant data is available when your
tags need them.

## Installation

For Tag Manager web page installations, you must create a data layer. The
following code example shows where the data layer is established, before Tag
Manager is loaded.

    \<script\>
    window.dataLayer = window.dataLayer \|\| \[\];
    \</script\>
    <!-- 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-XXXXXX');</script>
    <!-- End Google Tag Manager -->

In standard gtag.js implementations where the tag has been copied from within
the product and added to a web page, the code to establish the data layer is
provided. In custom implementations of the Google tag, add the data layer code
at the beginning of your script, as shown in the following code example:

    <!-- Google tag -->
    <script async src="https://www.googletagmanager.com/gtm.js?id=TAG_ID"></script>
    <script>
      window.dataLayer = window.dataLayer \|\| \[\];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
    </script>

> [!NOTE]
> **Note:** The container ID in the snippet source URL (such as `GTM-` versus `G-` or `AW-`) determines its script execution permissions and capabilities. For details, see [Container types and ID prefixes](https://developers.google.com/tag-platform/devguides/prerequisites#container_types_and_id_prefixes).

## How data layer information is processed

When a container is loaded, Tag Manager will begin to process all queued data
layer push messages. Tag Manager processes messages on a first-in, first-out
basis: Each message is processed one at a time, in the order it was received. If
the message is an event, any tags with trigger conditions that have been met
will fire before Tag Manager moves on to the next message.

If a `gtag()` or `dataLayer.push()` call is made by code on a page, in a Custom
Template, or in a Custom HTML tag, the associated message is queued and
processed after all other pending messages are evaluated. This means that any
updated data layer values are not guaranteed to be available for the next event.
To handle these cases, you should [add an event name to a message](https://developers.google.com/tag-platform/tag-manager/datalayer#use_a_data_layer_with_event_handlers) as it is
pushed to the data layer, and then listen for that event name with a
[Custom Event trigger](https://support.google.com/tagmanager/answer/7679219).

> [!IMPORTANT]
> **Important:** Don't use the [Custom HTML tags](https://support.google.com/tagmanager/answer/6107167#CustomHTML) to deploy gtag.js-based code. Instead, use Tag Manager's native tag templates for [Google Ads](https://support.google.com/tagmanager/topic/6334091), [Analytics](https://support.google.com/tagmanager/topic/6333310), and [Floodlight](https://support.google.com/tagmanager/topic/6334112).

> [!IMPORTANT]
> **Important:** Don't use Custom HTML tags to configure [consent settings in Tag Manager](https://support.google.com/tagmanager/answer/10718549). Because consent settings need to be applied before the relevant tags fire in a Tag Manager container, you must apply [Tag Manager Consent APIs](https://developers.google.com/tag-platform/tag-manager/templates/consent-apis) to configure default and update behavior. Use the [Tag Manager Consent APIs](https://developers.google.com/tag-platform/tag-manager/templates/consent-apis) to make sure consent updates are processed before any queued items in the data layer so that all tags fired by the same event see the same consent state.

> [!IMPORTANT]
> **Key Point:** You can use [Google Tag Assistant](https://tagassistant.google.com) to inspect the status of your data layer at any point in a chain of events.

## Use a data layer with event handlers

The `dataLayer` object uses an `event` command to initiate the sending of
events.

The Google tag and Tag Manager use a special data layer variable called
`event` that is used by JavaScript event listeners to fire tags when a user
interacts with website elements. For example, you may want to fire a conversion
tracking tag when a user clicks a purchase confirmation button. Events may be
called whenever a user interacts with website elements such as links, buttons,
scrolls, etc.

This functionality is accomplished by calling `dataLayer.push()` when an event
occurs. The syntax for sending an event with `dataLayer.push()` is as follows:

    dataLayer.push({'event': 'event_name'});

Where `event_name` is a string that describes the event, such as `'login'`,
`'purchase'`, or `'search'`.

Use `dataLayer.push()` to send event data when an action occurs that you'd like
to measure. For example, to send an event when a user clicks a button, modify
the button's `onclick` handler to call `dataLayer.push()`:

    <button onclick="dataLayer.push({'event': 'login'});">Button 1</button>

You can push data layer variables to the data layer dynamically to capture
information such as values entered or selected in a form, metadata
associated with a video that the visitor is playing, the color of a product
(for example, a car) customized by the visitor, the destination URLs of
clicked links, etc.

As with events, this functionality is accomplished by calling the `push()` API
to add or replace data layer variables in the data layer. The basic syntax for
setting dynamic data layer variables is as follows:

    dataLayer.push({'variable_name': 'variable_value'});

Where `'variable_name'` is a string indicating the name of the data layer
variable to be set, and `'variable_value'` is a string indicating the value of
the data layer variable to be set or replaced.

For example: To set a data layer variable with a color preference when a visitor
engages with a product customization tool, you might push the following dynamic
data layer variable:

    dataLayer.push({'color': 'red'});

## One push, multiple variables

You can push multiple variables and events at once:

    dataLayer.push({
      'color': 'red',
      'conversionValue': 50,
      'event': 'customize'
    });

> [!IMPORTANT]
> **Important:** If you push a variable with the same name as an existing variable to the data layer, the existing value will be overwritten by the new value.

## Persist data layer variables

To persist data layer variables between web pages, call `dataLayer.push()` after
the data layer has been instantiated on each page load, and push the variables
to the data layer. If you want these data layer variables to be available to Tag
Manager when the container is loaded, add a `dataLayer.push()` call above the
Tag Manager container code as shown in the following example:

    <script>
    window.dataLayer = window.dataLayer || [];

    dataLayer.push({
    'event': 'Pageview',
    'pagePath': 'https://www.googleanalytics.dev/pancakes',
    'pageTitle': 'Pancake Event Signup',
    'visitorType': 'customer'
    });
    </script>
    <!-- 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-XXXXXX');</script>
    <!-- End Google Tag Manager -->

Each variable declared within the data layer object will persist only as long
as the visitor remains on the current page. Data layer variables that are
relevant across pages (for example, `visitorType`) must be declared in the
data layer on each page of your website. While you don't need to put the
same set of variables in the data layer on every page, you should use a
consistent naming convention. In other words: if you set the page category on
the signup page using a variable called `pageCategory`, your product and
purchase pages should use the `pageCategory` variable as well.

## Troubleshooting

Here are some data layer troubleshooting tips:

**Do not overwrite the `window.dataLayer` variable:** When you use the data
layer directly (for example, `dataLayer = [{'item': 'value'}]`), it will
overwrite any existing values in the `dataLayer`. Tag Manager installations
should instantiate the data layer as high up in the source code as possible,
above the container snippet, using `window.dataLayer = window.dataLayer || [];`.
After the `dataLayer` has been declared, use `dataLayer.push({'item': 'value'})`
to add additional values to it, and if those values need to be available to
Tag Manager when the page loads, then that `dataLayer.push()` call needs to be
above the Tag Manager container code as well.

**The `dataLayer` object name is case-sensitive:** If you try to push a variable
or event without the proper casing, the push won't work.

    datalayer.push({'pageTitle': 'Home'});    // Bad (datalayer in lowercase)
    dataLayer.push({'pageTitle': 'Home'});    // Good (dataLayer in camel case)

`dataLayer.push` must be called with valid JavaScript objects. All data layer
variable names should be enclosed in quotes.

    dataLayer.push({new-variable: 'value'});      // Bad - no quote marks
    dataLayer.push({'new-variable': 'value'});    // Good - proper quote marks

**Keep variable names consistent across pages:** If you use different variable
names for the same concept on different pages, your tags will be unable to
consistently fire in all intended locations.

**Bad:**

    // Homepage:
    dataLayer.push({'visitorType': 'low-value'});

    // Checkout Page:
    dataLayer.push({'visitor_type': 'high-value'});

**Good:**

    // Homepage:
    dataLayer.push({'visitorType': 'low-value'});

    // Checkout Page:
    dataLayer.push({'visitorType': 'high-value'});

## Rename the data layer

The default name of the data layer object initiated by the Google tag or
Tag Manager is `dataLayer`. If you'd prefer to use a different name for your
data layer, you may do so by editing the data layer parameter value in your
Google tag or Tag Manager container snippet with the name of your choice.

### Tag Manager

Replace the data layer parameter value (highlighted below) in your container
snippet with the name of your choice.

> [!IMPORTANT]
> **Important:** Do *not* replace the non-highlighted parameter value.

    <!-- 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','myNewName','GTM-XXXXXX');</script>
    <!-- End Google Tag Manager -->

### gtag.js

Add a query parameter named "l" to the URL to set the new data layer name,
for example, `l=myNewName`. Update all instances of `dataLayer` in the
Google tag snippet to the new name.

    <!-- Google tag -->
    <script async src="https://www.googletagmanager.com/gtm.js?id=TAG_ID&l=myNewName"></script>
    <script>
      window.myNewName = window.myNewName || [];
      function gtag(){myNewName.push(arguments);}
      gtag('js', new Date());
    </script>

Once renamed, all references to your data layer (i.e. when declaring the data
layer above the snippet, or when pushing events or dynamic data layer variables
to the data layer with the `.push()` command) must be adjusted to reflect your
custom data layer name:

    <script>
      window.myNewName = window.myNewName \|\| \[\];
      window.myNewName.push({'variable_name': 'variable_value'});
    </script>

> [!WARNING]
> **Important: Use only one data layer per page**
>
> Only one `dataLayer` object is supported per page. Google Tag Manager and gtag.js rely on a single, global JavaScript array named `window.dataLayer` to receive, queue, and process all events and variables in the order they are added. The container snippets attach their listeners and processing logic specifically to this single array. Attempting to use more than one data layer instance, or incorrectly re-initializing the data layer (for example, overwriting it with `window.dataLayer = []` after GTM has loaded), can cause significant problems:
>
> - **Tags may not fire:** Events and variables pushed to an instance of `dataLayer` that Google Tag Manager or the Google tag is not actively monitoring won't trigger your tags.
> - **Inconsistent data collection:** Different parts of your page or different scripts might push data to separate, isolated `dataLayer` arrays, leading to incomplete or incorrect information reaching your analytics and marketing tags.
> - **Data loss:** Information intended for tracking may be lost if sent to the wrong `dataLayer` instance.
> - **Debugging challenges:** It is difficult to diagnose tagging issues since the flow of tracking data is unpredictable.
>
> **Best practice:** Always instantiate the data layer using `window.dataLayer = window.dataLayer || [];` once per page, typically high in the page's `<head>` before the GTM or gtag.js snippet. Always use `dataLayer.push()` to add subsequent events or variables. Never overwrite or re-assign the `window.dataLayer` variable.

## Custom data layer methods

If you push a function to the data layer, it will be invoked with `this` set
to an abstract data model. This abstract data model can get and set values to
a key value store, and also provides a way to reset the data layer.

> [!IMPORTANT]
> **Important:** To use custom data layer methods, you must use `.push` to send data to the `dataLayer` variable directly. If you use `gtag`, the function will be interpreted as an invalid command and ignored.

### set

The `set` function on the abstract data model lets you set values to retrieve
through get.

    window.dataLayer.push(function() {
      this.set('time', new Date());
    });

### get

The `get` function on the abstract data model lets you retrieve values that
were set.

    window.dataLayer.push(function() {
      const existingTime = this.get('time');
      if (existingTime !== null) {
        // Change behavior based on whether or not this value exists...
      } else {
        // ...
      }
    });

### reset

The `reset` function on the abstract data model lets you reset the data in the
data layer. This is most useful with a page that will remain open and the data
layer size continues to grow over time. To reset the data layer, use the
following code:

    window.dataLayer.push(function() {
      this.reset();
    });