The Core Components provide an out-of-the-box integration with the Adobe Client Data Layer and Google Tag Manager Data Layers. For convenience these are referred to in the page as ACDL and GDL.
The data layer is disabled by default.
To enable the data layer for your site:
- Create the following structure below the
/conf
node:/conf/<my-site>/sling:configs/com.adobe.cq.wcm.core.components.internal.DataLayerConfig
- Add the
enabled
boolean property and set it totrue
. - If a datalayer object name other than
adobeDataLayer
is required (e.g.dataLayer
for most GDLs), add a string propertyname
to the same node, with the required Data Layer object name as the value. - Add a
sling:configRef
property to thejcr:content
node of your site below/content
(e.g./content/<my-site>/jcr:content
) and set it to/conf/<my-site>
While Core Components includes the ACDL Library unless explicitly disabled (below), it does not include the GDL library. The Core Components code will create an appropriately named Data Layer array, but a standard Google Tag Manager code snippet must be included in the page to consume this array and create a full GDL. This is done according to Google documentation and is not directly related to Core Components.
Google's GTag code is not currently supported.
The Core Components Data Layer integration supports Data Layer name configuration, and the logic uses the standard JavaScript array push() method. If the Data Layer is enabled, but the ACDL library is not loaded, and the Data Layer is not consumed by a Google solution, there will still be a plain JavaScript array available with the configured name, and containing Core Components data, although with 'event' entries that are intended for an Event-Driven Data Layer like the ACDL or GDL. This plain array Data Layer is generic and may be suitable for other Data Layer providers or consumers.
The ACDL library is included by default by the Page component. If using a GDL, or already including the ACDL library in some other way such as using AEP Data Collection Tags, the ACDL library should not be loaded.
To prevent the ACDL library from being included by the Page component:
- Create the following structure below the
/conf
node:/conf/<my-site>/sling:configs/com.adobe.cq.wcm.core.components.internal.DataLayerConfig
- Add the
skipClientlibInclude
boolean property and set it totrue
. - Add a
sling:configRef
property to thejcr:content
node of your site below/content
(e.g./content/<my-site>/jcr:content
) and set it to/conf/<my-site>
When the data layer is enabled, a JavaScript Data Layer object will be available. By default, the object name is adobeDataLayer
. If a name has been defined in the Data Layer configuration (see Enabling the Data Layer) the object will be named accordingly. The Data Layer will be populated with the components and their properties that are used on the page.
If an ACDL is used the data layer state (returned by calling adobeDataLayer.getState()
) is an object with two objects (page
and component
). All the components are stored below the component
object as a flat structure. The structure looks as follows:
{
"page": {
"page-id": {
"key1": "value1,
"key2": "value2,
}
},
"component": {
"component-id1": {
"key1": "value1,
"key2": "value2,
},
"component-id2": {
"key1": "value1,
"key2": "value2,
},
...
}
}
Calling adobeDataLayer.getState()
in the browser console will return e.g.:
{
"page": {
"page-df1699a779": {
"xdm:tags": [],
"xdm:language": "en-GB",
"xdm:template": "/conf/core-components-examples/settings/wcm/templates/content-page",
"repo:path": "/content/core-components-examples/library/core-content/title.html",
"dc:title": "Title",
"@type": "core-components-examples/components/page",
"repo:modifyDate": "2020-05-28T08:46:44Z",
"dc:description": "Display a page heading"
}
},
"component": {
"image-1bd0710a59": {
"image": {
"xdm:tags": [],
"repo:id": "401835a1-832c-427f-a508-c7f55495a4df",
"repo:modifyDate": "2020-05-28T08:46:49Z",
"@type": "image/svg+xml",
"repo:path": "/content/dam/core-components-examples/library/aem-corecomponents-logo.svg"
},
"dc:title": "AEM Core Components",
"xdm:linkURL": "/content/core-components-examples/library.html",
"@type": "core-components-examples/components/image",
"repo:modifyDate": "2019-01-09T16:58:39Z",
"parentId": "page-df1699a779"
},
"accordion-3b90a50076": {
"shownItems": [
"accordion-3b90a50076-item-6b9d62c47d",
"accordion-3b90a50076-item-f05b6c6615",
"accordion-3b90a50076-item-f3fcd996f5",
"accordion-3b90a50076-item-cd527eac50"
],
"@type": "core-components-examples/components/accordion",
"repo:modifyDate": "2020-01-14T16:59:24Z",
"parentId": "page-df1699a779"
},
"title-13869e3afb": {
"dc:title": "Standard",
"@type": "core/wcm/components/title/v2/title",
"repo:modifyDate": "2018-12-07T12:49:20Z",
"parentId": "page-df1699a779"
},
"text-c36e0b2cf9": {
"@type": "core/wcm/components/text/v2/text",
"repo:modifyDate": "2018-12-07T12:49:23Z",
"xdm:text": "<p>Default title without any configuration. The title is taken from the current page.</p>\n",
"parentId": "page-df1699a779"
}
}
}
Google Data Layers do not have a getState() method which can provide a consolidated computed state of the Data Layer. To view the raw Data Layer enter the name of the Data Layer in the browser console, e.g. dataLayer
. The computed state can be viewed using Google and third party debugging tools.
The following table shows the components supporting the data layer:
Components | Data Layer Support |
---|---|
Accordion | x |
Breadcrumb | x |
Button | x |
Carousel | x |
Container | |
Content Fragment | x |
Content Fragment List | |
Download | |
Embed | |
Experience Fragment | |
Form button | |
Core Form container | |
Form hidden field | |
Form options field | |
Form text field | |
Image | x |
Language Navigation | x |
List | x |
Navigation | x |
Page | x |
Progress Bar | x |
Quick Search | |
Separator | |
Sharing | |
Tabs | x |
Teaser | x |
Text | x |
Title | x |
Schema used for all the components that are not listed below.
id: { // component ID
@type // resource type
repo:modifyDate // last modified date
dc:title // title
dc:description // description
xdm:text // text
xdm:linkURL // link URL
parentId // parent component ID
}
Schema used for the Accordion, the Carousel and the Tabs components.
id: {
@type
repo:modifyDate
dc:title
dc:description
xdm:text
xdm:linkURL
parentId
shownItems // array of the displayed item IDs
}
Schema used for the Content Fragment:
id: {
@type
repo:modifyDate
dc:title
dc:description
xdm:text
xdm:linkURL
parentId
elements // array of the Content Fragment elements
}
Schema used for the Content Fragment element:
{
xdm:title // title
xdm:text // text
}
Schema used for the Page component:
id: {
@type
repo:modifyDate
dc:title
dc:description
xdm:text
xdm:linkURL
parentId
xdm:tags // page tags
repo:path // page path
xdm:template // page template
xdm:language // page language
}
Schema used for the Image component:
id: {
@type
repo:modifyDate
dc:title
dc:description
xdm:text
xdm:linkURL
parentId
image // asset detail (see below section)
}
Schema used inside the Image component schema:
id: {
repo:id // asset UUID
repo:path // asset path
@type // asset resource type
xdm:tags // asset tags
repo:modifyDate
}
When the data layer is enabled, the body element has a data-cmp-data-layer-enabled
attribute.
The Core Components supporting the data layer have a data-cmp-data-layer
attribute populated with the component properties as defined by the component model.
Clickable elements of the Core Components (e.g. links, buttons) have a data-cmp-clickable
attribute (see below for more details about the events).
Clicking a clickable element (an element that has a data-cmp-clickable
attribute) makes the data layer trigger a cmp:click
event.
Manipulating the accordion (expand/collapse), the carousel (next/previous buttons) and the tabs (tab select) components makes the data layer trigger respectively a cmp:show
and a cmp:hide
event.
As soon as the data layer is populated with the core components available on the page, the data layer triggers a cmp:loaded
event.
The JSON rendering of a Core Component exposes a dataLayer
property that is populated with the data layer specific properties defined by the component model. E.g.:
"dataLayer": {
"title-b358cbbf54": {
"dc:title": "Lorem Ipsum",
"@type": "core/wcm/components/title/v2/title",
"repo:modifyDate": "2018-12-07T12:53:27Z"
}
}
To automatically add a custom component to the data layer:
- Define the properties of the custom component model that needs to be tracked.
- Add the
data-cmp-data-layer
attribute to the custom component HTL. E.g.data-cmp-data-layer="${mycomponent.data.json}"
.
To automatically make the data layer trigger a cmp:click
event each time a specific element of the custom component is clicked:
in the custom component HTL add the data-cmp-clickable
attribute to the element to be tracked.
The data-cmp-data-layer-enabled
attribute can be queried client side to check if the data layer is enabled.
This section shows how to add some data from a HelloWorld
component to the data layer.
Create a HelloWorld
model and HTL script that prints "Hello World!" to the page:
HelloWorld
model:
package mymodels;
...
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
...
@Model(adaptables = SlingHttpServletRequest.class)
public class HelloWorld {
@SlingObject
protected Resource resource;
public String getMessage() {
return "Hello World!";
}
}
HelloWorld
HTL script:
<div data-sly-use.hello="mymodels.HelloWorld">
${hello.message}
</div>
Deploy the model and the HTL script to a running AEM instance and add this component to a page. Run the following code in your browser console:
adobeDataLayer.getState()
The HelloWorld
component does not yet write to the data layer.
Let's add custom properties (ID, description and parent ID) based on custom implementations to the data layer.
Add following code to the HelloWorld
model:
...
import com.adobe.cq.wcm.core.components.models.datalayer.ComponentData;
import com.adobe.cq.wcm.core.components.models.datalayer.builder.DataLayerBuilder;
import com.adobe.cq.wcm.core.components.util.ComponentUtils;
...
public ComponentData getData() {
if (ComponentUtils.isDataLayerEnabled(this.resource)) {
return DataLayerBuilder.forComponent()
.withId(() -> "hello-123")
.withDescription(this::getMessage)
.withParentId(() -> "parent-12")
.build();
}
return null;
}
Add the data-cmp-data-layer
attribute to the component HTL:
<div data-sly-use.hello="mymodels.HelloWorld"
data-cmp-data-layer="${hello.data.json}">
${hello.message}
</div>
Deploy the changes to AEM (model and HTL script). Refresh the page and in your browser console, get the state of the data layer:
adobeDataLayer.getState()
It displays something like:
hello-123:
dc:description: "Hello World!"
parentId: "parent-12"