# Amazon S3 URL: https://docs.contentsquare.com/en/connect/amazon-s3/ Amazon S3 (Simple Storage Service) is an object storage service that offers industry-leading scalability, data availability, security, and performance. The Data Connect integration with S3 allows you to export your Contentsquare data to S3 for flexible storage and analysis options. Unlike the other warehouse integrations (BigQuery, Redshift, Snowflake), the S3 integration provides raw data files that you can process with your preferred analytics tools, such as Athena, EMR, or third-party data processing services. ## Prerequisites Before setting up the S3 integration, ensure you have: - **An AWS account** with S3 access - **An S3 bucket** to store Contentsquare data - **AWS credentials** with appropriate permissions for the S3 bucket ## S3 setup 1. Create an S3 bucket to store Contentsquare data (if you don't already have one) 1. Create an IAM user or role with appropriate permissions: - The IAM policy should include: - `s3:PutObject` - `s3:GetObject` - `s3:ListBucket` - `s3:DeleteObject` (optional, for cleanup) 1. Generate AWS access keys for the IAM user (if using user-based authentication) ## Configure Data Connect :::warning[Admin only] Configuration of this destination is only available to admin users in Contentsquare. ::: 1. Log in to Contentsquare. 1. Navigate to **Analysis setup** > **Data Connect**. 1. Create the S3 bucket `csq-rs3-` to sync Data Connect data with. 1. Select **Next**. 1. Add the displayed policy to your CSQ bucket on S3. 1. Input your S3 credentials to connect to your bucket. 1. Select **Connect**. Once setup is complete, you’ll see a sync within 24 hours with the following built-in tables. ## Data Structure in S3 When Data Connect syncs data to S3, it creates the following structure: ``` s3://your-bucket/[optional-prefix]/ ├── users/ │ ├── date=YYYY-MM-DD/ │ │ ├── part-00000.[format].[compression] │ │ ├── part-00001.[format].[compression] │ │ └── ... ├── sessions/ │ ├── date=YYYY-MM-DD/ │ │ ├── part-00000.[format].[compression] │ │ ├── part-00001.[format].[compression] │ │ └── ... ├── pageviews/ │ ├── date=YYYY-MM-DD/ │ │ └── ... ├── [custom_event_name]/ │ ├── date=YYYY-MM-DD/ │ │ └── ... └── ... ``` The data is organized by: - Table name (users, sessions, pageviews, custom events) - Date partition (based on sync date) - Part files (data is split into multiple files) --- # Merchandising implementation URL: https://docs.contentsquare.com/en/catalog-merchandising/ This page helps make your website product catalog available to sync with Merchandising. Keeping your catalog up to date and reflecting your live site is key to getting the full value from Merchandising. There are two parts to this process and both need to be completed as soon as possible: - Implementing Merchandising web tracking on your site - Making your product catalog available to Contentsquare ## Implementing web tracking You'll need to complete the following key tasks: - Use our [Sending products purchased documentation](/en/web/sending-ecommerce-commands/#sending-a-transaction-for-merchandising) to implement the tracking of the product purchased. - Use our [Add to Cart documentation](/en/web/sending-an-add-to-cart/) to send a product’s exact SKU to Merchandising whenever a user adds it to their cart. ## Content needed from your catalog To benefit from Merchandising’s capabilities you’ll also need to provide an updated catalog version that contains all products visible on your site, at all times. Contentsquare is only able to capture data about a product if it is in your product catalog. ![](~/assets/catalog-merchandising/merch-catalog.png) ### Products to include - Any product that is visible on the site should be in the product catalog (even if they are out of stock). - If you are launching a new product, make sure it is in your product catalog before launching it on your site. ### Catalog format The product catalog must be provided in either `.CSV`, `.TSV`, `.XML`, or Google Sheets format. :::note For Google Sheets, the catalog must be accessible publicly. ::: ### Catalog content We will be able to map the name of the columns of your catalog with our system, the wording for the information below is just an example. The catalog must contain, at least, the following information: | Information | Purpose | Validation | | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | SKU | Identifies the product SKU. | It must exactly match the SKU that is pushed in the Contentsquare Tag for 'Transactions' and 'Add to Cart'.

It has to be unique. | | Model ID | In case of products that have variants, this ID must be common to the SKUs (variants) of the same product.

If it’s necessary, Contentsquare will provide all Merchandising data aggregated on the Model ID. | | | Name | Identifies the product name

It's needed to display the name of the product in the Merchandising solution. | It’s preferable that it is unique to avoid confusion with another product. | | Category | Identifies the product category.

It's needed to classify the products according to their category tree. | It has to use the following format: Shoes > Men > Boots

nb: the ">" separator used can be different

We can only have 1 categorization per product | | URL | Identifies the product page URL on the site

It can be used to match the visits and appearance of the product on the website with the product in the catalog | The URL must be complete (protocol + domain + path)

It has to match with the website's product page URL

The URL will be stripped of queries and fragments | | Image URL | URL link to the product image

It's needed to display the product image in the Merchandising solution | Only 1 URL should be indicated in the field

The URL must be complete (protocol + domain + path) | | Brand | Indicates the name product brand

It allows to have aggregated KPIs for a given brand | | | Price | Indicates the unit price of the product.

If the product is discounted, the discounted price can be placed in this field or put in another field.

It's needed to run competitive data analysis, comparing your prices with competitors' | | | Shipping fees | Indicates the product's shipping fees

It's only needed for competitive data analysis to compare shipping fees with your competitors' | It's optional | | gtin / EAN / UPC | Indicates the EAN / GTIN / UPC of the product. It’s a unique id of the product on the market

It's used to match products with your competitors' when running competitive analysis. | It has to be unique

We currently support the following formats: EAN, UPC, GS1, ITF | | Currency | Identifies the product price's currency | | | Stock availability

(mandatory if you want to benefit from stock insights, otherwise optional) | Indicates if the product is "in stock" or "out of stock" | | | Stock quantity

(mandatory if you want to benefit from stock insights, otherwise optional) | Indicates the stock quantity of the product | It must be a number | ### Provide your product catalog on a feed Contentsquare will synchronize your product catalog every hour to provide you with the most accurate insights. **Before Merchandising can sync with your catalog, you’ll need to make it available on a feed.** Make your catalog available on a feed using either of these options: - Provide a URL link that downloads the catalog - [Upload it on Contentsquare’s Secured FTP](#upload-your-catalog-on-contentsquares-secured-ftp) Once you have chosen a method, let our Implementation Team know so they can assist you. #### Upload your catalog on Contentsquare's secured FTP :::note With this option, you are responsible for uploading and maintaining your catalog up-to-date. ::: Provide the Implementation team with: - The IP address from which the catalog will be uploaded and to allowlist. - A public key in OpenSSH format, for authentication purposes. - The exact name of the catalog file that is to be uploaded. In turn, Contentsquare will provide you with: - The SFTP URL. - The username (project ID) to perform the upload. To update the last-in-date catalog, use your private key to authenticate and upload the file. --- # BigQuery URL: https://docs.contentsquare.com/en/connect/bigquery/ Google BigQuery is a fully managed, serverless data warehouse that enables scalable analysis over petabytes of data. The Data Connect integration with BigQuery allows you to automatically sync your Contentsquare data to BigQuery for advanced analysis and joining with other business data. :::tip As part of this integration, Contentsquare creates the dataset in BigQuery for you during the initial sync. You do not need to create it manually. ::: ## Prerequisites Before setting up the BigQuery integration, ensure you: 1. [Have a Google Cloud Platform (GCP) project](https://support.google.com/cloud/answer/6251787?hl=en&ref_topic=6158848). 1. [Enable billing in the GCP project](https://cloud.google.com/billing/docs/how-to/modify-project). 1. [Enable the BigQuery API](https://console.cloud.google.com/flows/enableapi?apiid=bigquery) 1. Know the region you want to use among `us`, `eu`, `europe-west1`, `europe-west2`, `us-central1`, `us-west1`, `us-west2`, `australia-southeast1`, `europe-west6`, or `us-east4`. 1. (Optional) Decide on a name for your dataset (default is `project_environment`). These prerequisites are also outlined in Google Cloud Platform [quick-start guide](https://cloud.google.com/bigquery/quickstart-web-ui) ## BigQuery setup Within the [GCP dashboard](https://console.cloud.google.com/home/dashboard) for your selected project, visit `IAM & admin` settings and click **+ Add**. In the subsequent view, add `heap-sql@heap-204122.iam.gserviceaccount.com` as a `BigQuery User` and save the new permission. We would prefer to be added as a BigQuery user per the steps above. At minimum, we need to be assigned to a `dataEditor` role, and we need the following permissions: **Project Permissions** - `bigquery.datasets.get` - `bigquery.jobs.create` **Dataset Permissions** - `bigquery.routines.create` - `bigquery.routines.delete` - `bigquery.routines.get` - `bigquery.routines.list` - `bigquery.routines.update` - `bigquery.tables.create` - `bigquery.tables.delete` - `bigquery.tables.get` - `bigquery.tables.getData` - `bigquery.tables.list` - `bigquery.tables.update` - `bigquery.tables.updateData` See BigQuery's [access control](https://cloud.google.com/bigquery/docs/access-control) doc to learn more about the different roles in BigQuery, and see this [StackOverflow response](https://stackoverflow.com/questions/42569095/how-can-i-grant-individual-permissions-in-google-cloud-platform-for-bigquery-use) for steps to grant individual permissions to create a [custom IAM role](https://console.cloud.google.com/projectselector2/iam-admin/iam) for Contentsquare. ## Configure Data Connect :::warning[Admin only] Configuration of this destination is only available to admin users in Contentsquare. ::: 1. Log in to Contentsquare. 1. Navigate to **Analysis setup** > **Data Connect**. 1. Select **Connect** next to BigQuery 1. Enter your BigQuery hostname and select **Next**. 1. Supply the required information: - Your **Project ID**, which you can find in the `Project info` section of your GCP project dashboard (make sure you're in the correct project). - Your **region**: `us`, `eu`, `europe-west1`, `europe-west2`, `us-central1`, `us-west1`, `us-west2`, `australia-southeast1`, `europe-west6`, or `us-east4`. - The **dataset name override** if you don't want the default. The default dataset name is `project_environment`. For example, the Main Production environment will default to a dataset name of _main_production_. 1. Select **Connect**. --- # Connect Common Queries URL: https://docs.contentsquare.com/en/connect/common-queries/ This article provides a collection of common queries you can use with Data Connect. You can copy and paste these queries into your BI tool or run them directly on your cluster. Some queries may require you to update property names, event names, or date ranges to fit your specific needs. ## Basic Queries ### Event Counts ```sql SELECT device_type ,plan ,COUNT(session_id) FROM main_production.sessions AS sessions INNER JOIN main_production.users AS users ON sessions.user_id = users.user_id GROUP BY 1, 2 ``` ### Average Property Value ```sql SELECT [Property_to_Group_By], AVG([Numeric_Property]) ``` ## Modeling Your Data ### Creating An Enhanced Users Table This query provides an example of how to recreate the users table, adding the Initial User Properties (ex: Initial Referrer, Initial Browser, etc.) that are displayed in your Contentsquare account. ```sql BEGIN; DROP TABLE IF EXISTS enhanced_users; CREATE TABLE enhanced_users AS SELECT u.* ,s.time AS date_first_seen ,s.referrer AS initial_referrer ,s.utm_source AS initial_utm_source ,s.utm_medium AS initial_utm_medium ,s.utm_campaign AS initial_utm_campaign ,s.city AS initial_city ,s.region AS initial_region ,s.country AS initial_country FROM main_production.users u JOIN (SELECT user_id ,MIN(time) AS earliest_time FROM main_production.sessions GROUP BY 1) fs ON u.user_id = fs.user_id JOIN main_production.sessions s ON fs.user_id = s.user_id AND fs.earliest_time = s.time; COMMIT; ``` ## Aggregate Metrics In this section, you'll find various queries to measure aggregate metrics for your site, including average time, top events, and more. The value of these queries increases as you segment them by user personas, and the same logic can also be applied to calculate more specific statistics. ### Top 10 Events The top 10 events shed light on how users are interacting with your app. Looking at this list can generate insights about user behavior patterns. ```sql SELECT event_type ,COUNT(*) AS events FROM main_production.all_events WHERE time >= CURRENT_DATE - INTERVAL '30 days' GROUP BY 1 ORDER BY 2 DESC LIMIT 10 ``` You can modify the `WHERE` statement to adjust the date range. You can include the date in the `SELECT` statement and `GROUP BY` to see how the top events change over time. ### Retention This query calculates session-to-session retention analysis on a monthly basis. Each user is segmented into a cohort based on the month of their join date and is counted in the total retained on a monthly basis if they have a session during each month. ```sql WITH first_session AS ( SELECT user_id , DATE_TRUNC('month', MIN(time)) AS cohort_month FROM main_production.sessions GROUP BY 1 ), months AS ( SELECT DISTINCT DATE_TRUNC('month', time) AS session_month FROM main_production.sessions ), user_sessions AS ( SELECT s.user_id , DATE_TRUNC('month', s.time) AS session_month , f.cohort_month FROM main_production.sessions s JOIN first_session f ON s.user_id = f.user_id GROUP BY 1, 2, 3 ) SELECT cohort_month , session_month , COUNT(DISTINCT user_id) AS active_users , MAX(COUNT(DISTINCT user_id)) OVER (PARTITION BY cohort_month) AS total_users , COUNT(DISTINCT user_id)::FLOAT / MAX(COUNT(DISTINCT user_id)) OVER (PARTITION BY cohort_month) AS retention_rate FROM user_sessions GROUP BY 1, 2 ORDER BY 1, 2 ``` ### Bounce Rate ```sql WITH data AS ( SELECT time::date AS day, session_id, count(*) AS pageviews FROM heap_production.pageviews GROUP BY 1, 2 ) SELECT day, count(CASE WHEN pageviews = 1 THEN 1 ELSE NULL END) / count(*) AS bounce_rate FROM data GROUP BY 1 ORDER BY 1 ``` ## Funnels This section covers Data Connect queries that enable you to conduct funnel analysis by measuring all types of funnels. Funnels are fundamental to understanding any flow through your site, from onboarding to filling out forms, to virtually any step users are expected to take within your product. ### Basic Funnel ```sql WITH funnel AS ( SELECT user_id , MIN(CASE WHEN event_name = 'view_signup_page' THEN time END) AS view_signup , MIN(CASE WHEN event_name = 'submit_signup_form' THEN time END) AS submit_signup , MIN(CASE WHEN event_name = 'complete_onboarding' THEN time END) AS complete_onboarding FROM main_production.all_events WHERE time >= CURRENT_DATE - INTERVAL '30 days' GROUP BY 1 ) SELECT COUNT(DISTINCT user_id) AS total_users ,COUNT(DISTINCT CASE WHEN view_signup IS NOT NULL THEN user_id END) AS viewed_signup ,COUNT(DISTINCT CASE WHEN submit_signup IS NOT NULL THEN user_id END) AS submitted_signup ,COUNT(DISTINCT CASE WHEN complete_onboarding IS NOT NULL THEN user_id END) AS completed_onboarding FROM funnel ``` ### Average Time Between Events ```sql WITH event_times AS ( SELECT user_id ,MIN(CASE WHEN event_name = 'first_event' THEN time END) AS first_event_time ,MIN(CASE WHEN event_name = 'second_event' THEN time END) AS second_event_time FROM main_production.all_events GROUP BY 1 ) SELECT AVG(EXTRACT(EPOCH FROM (second_event_time - first_event_time))) / 60 AS avg_minutes_between_events FROM event_times WHERE first_event_time IS NOT NULL AND second_event_time IS NOT NULL AND second_event_time > first_event_time ``` ## Attribution This section covers Data Connect queries that enable you to measure attribution to better understand where your users are coming from. ### Top Referrers This query returns the top N referrers and the number of sessions they generate. ```sql SELECT referrer ,COUNT(*) AS sessions FROM main_production.sessions WHERE referrer IS NOT NULL GROUP BY 1 ORDER BY 2 DESC LIMIT 10 ``` ### First Touch Properties This query generates a table that matches Contentsquare's Users view. You can export and select all the user-level properties and all the first touch properties. #### How it works This query starts by calculating the first session for each user and joins the first sessions data with the users table based on the unique user ID. From here, each user-level property and session-level property can be selected. ```sql SELECT u.* ,s.time AS date_first_seen ,s.referrer AS initial_referrer ,s.utm_source AS initial_utm_source ,s.utm_medium AS initial_utm_medium ,s.utm_campaign AS initial_utm_campaign FROM main_production.users u JOIN (SELECT user_id ,MIN(time) AS earliest_time FROM main_production.sessions GROUP BY 1) fs ON u.user_id = fs.user_id JOIN main_production.sessions s ON fs.user_id = s.user_id AND fs.earliest_time = s.time ``` ## Revenue Analysis One of the most powerful aspects of Data Connect is the ability to join a complete set of user interactions with other data sources to see revenue data, such as a user's order history. ### ARPU per UTM Source This query combines Contentsquare's attribution data with order history data, allowing you to compare how each source is correlated with a user's downstream behavior. ```sql WITH first_touch AS ( SELECT all_sessions.user_id ,identity ,first_session.first_time AS first_seen ,utm_source -- add any user level properties or session level properties here FROM main_production.sessions AS all_sessions JOIN (SELECT user_id ,MIN(time) AS first_time FROM main_production.sessions GROUP BY 1) AS first_session ON all_sessions.user_id = first_session.user_id AND all_sessions.time = first_session.first_time ) SELECT utm_source ,COUNT(DISTINCT identity) AS users ,SUM(payment_amount) AS revenue ,SUM(payment_amount) / COUNT(DISTINCT identity) AS arpu FROM first_touch LEFT JOIN main_production.orders ON first_touch.identity = main_production.orders.identity WHERE utm_source IS NOT NULL GROUP BY 1 ORDER BY 4 DESC ``` ## Average Time on Page This query calculates the average time spent on each page, helping you identify which content is most engaging for your users. ```sql SELECT path ,AVG(EXTRACT(EPOCH FROM (next_time - time))) AS avg_seconds_on_page FROM ( SELECT p1.session_id ,p1.user_id ,p1.path ,p1.time ,p2.time AS next_time ,p2.path AS next_path FROM ( SELECT * ,ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY time) AS rn FROM main_production.pageviews) p1 JOIN ( SELECT * ,ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY time) AS rn FROM main_production.pageviews) p2 ON p1.session_id = p2.session_id AND p1.rn + 1 = p2.rn -- optional filter to limit paths you're analyzing -- WHERE p1.path !~ '/app' GROUP BY p1.session_id, p1.user_id, p1.path, p1.time, p2.time) a GROUP BY 1 ORDER BY 2 DESC ``` ## Average Events per Session The average events per session metric can give you insight into aggregate behavior. This query can be modified to analyze behavior across segments and over time, allowing you to answer questions such as: - Does this number change with a product launch or tweaks to the onboarding flow? - Do different types of users interact differently? Changes in the average can prompt investigation into what is really happening within your app. ```sql SELECT COUNT(*) / COUNT(DISTINCT session_id) AS avg_events_per_session FROM main_production.all_events WHERE time >= CURRENT_DATE - INTERVAL '30 days' ``` --- # Data Warehouses URL: https://docs.contentsquare.com/en/connect/data-warehouses-overview/ import { IntegrationsNav } from "~/components"; Data Connect supports integration with several data warehouse platforms, allowing you to export your behavioral data for advanced analytics and joining with other business data. ## Start Frequency and Start Time | Feature | Amazon S3 (Retroactive) | BigQuery | Databricks | Redshift | Snowflake | | --------------------------------- | ----------------------- | ------------------- | ------------------- | ------------------- | ------------------- | | Supported Sync Frequency | Once every 24 hours | Once every 24 hours | Once every 24 hours | Once every 24 hours | Once every 24 hours | | Segment Syncing | Not Supported | Not Supported | Not Supported | Supported | Supported | | Defined Properties Syncing | Supported | Supported[^1] | Supported | Supported | Supported | | User Migration Syncing | Supported | Supported | Supported | Supported | Supported | | User Migrations Applied on Tables | Manually Applied[^2] | Automatic | Automatic | Automatic | Automatic | [^1]: Defined properties on the built-in pageviews or sessions tables are not included. [^2]: Requires manual application of identity resolution queries. --- # Data Schema URL: https://docs.contentsquare.com/en/connect/data-schema/ import { Badge } from "~/components"; This guide explains the schema structure of Contentsquare data in your data warehouse, helping you understand how to effectively query and analyze the data. Data Connect creates several tables in your data warehouse, each representing a different aspect of user behavior data. Understanding this schema is essential for effective analysis and joining with other data sources. Data Connect adopts a hierarchical schema. By default, Data Connect will sync the following tables: - One users table (for all user information) - One sessions table (for all session information) - One pageviews table (for all pageview information) Data Connect creates the following core tables in your data warehouse. ## users The `users` table contains a row for each unique user that has visited your site. | Column Name | Type | Description | | --------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `user_id` | BIGINT | Unique ID of user, randomly generated by Contentsquare (CSQ). | | `identity` | TEXT | User's username or other unique token, passed [identify](/en/web/command-reference/#identify). Must be unique. | | `handle` | TEXT | User's username or other unique token, passed [identify](/en/web/command-reference/#identify). | | `email` | TEXT | User's email address, passed in via [addUserProperties](/en/web/command-reference/#adduserproperties) API. | | `joindate` | TIMESTAMP | Timestamp without time zone of when the user was first seen. In S3, this is in UNIX timestamp format. | | `last_modified` | TIMESTAMP | Timestamp without time zone of when the user's data was last modified. In S3, this is in UNIX timestamp format. | | user properties | TEXT | There will be one column for every unique user property you've sent via the [addUserProperties](/en/web/command-reference/#adduserproperties) API (name, gender, account status, etc). The column type is automatically inferred from the underlying property values. | ## sessions The `sessions` table represents individual user sessions. | Column Name | Type | Library | Description | | ------------------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `event_id` | BIGINT | All | ID of associated session event, randomly generated by CSQ. | | `user_id` | BIGINT | All | ID of associated user, randomly generated by CSQ. | | `session_id` | BIGINT | All | ID of associated session, randomly generated by CSQ. | | `time` | TIMESTAMP | All | Timestamp without time zone of when session started. | | `library` | TEXT | All | Version of Contentsquare library which began the session. Can be one of "web" or "iOS". | | `platform` | TEXT | Web | User's operating system. | | `device_type` | TEXT | Web | Device type, which can only be one "Desktop". | | `country` | TEXT | All | Country in which user session occurred, based on IP. | | `region` | TEXT | All | Region in which user session occurred, based on IP. | | `city` | TEXT | All | City in which user session occurred, based on IP. | | `referrer` | TEXT | Web | URL that linked to your site and initiated the session. If the user navigated directly to your site, or referral headers were stripped, then this value will appear as NULL downstream and as `direct` in the UI. | | `landing_page` | TEXT | Web | URL of the first pageview of the session. | | `browser` | TEXT | Web | User's browser. | | `utm_source` | TEXT | Web | GA-based utm_source tag associated with the session's initial pageview. | | `utm_campaign` | TEXT | Web | GA-based utm_campaign tag associated with the session's initial pageview. | | `utm_medium` | TEXT | Web | GA-based utm_medium tag associated with the session's initial pageview. | | `utm_term` | TEXT | Web | GA-based utm_term tag associated with the session's initial pageview. | | `utm_content` | TEXT | Web | GA-based utm_content tag associated with the session's initial pageview. | | `custom_var` | TEXT | Web | key-value pairs that define more information about the pageview. | | `session_replay_link` | TEXT | Web | Contentsquare Platform url link of the session replay. | | `session_duration` | TEXT | Web | Total duration of the session. | | `session_language` | TEXT | Web | Language displayed during the session. | | `session_number_of_views` | TEXT | Web | The number of page views in the session. | | `frustration_score` | TEXT | Web | Measure of user frustration during the session. | | `looping_Index` | TEXT | Web | The proportion of same urls visited during the session (meaning the user is doing back & forth). | | `page_consumption` | TEXT | Web | Proportion of pages where the user spent less than 2s and did less than 2 clicks. | | `filtered_APV` | TEXT | Web | Number of views in which APVs (Artificial Pageviews) are not counted / a boolean determining whether a given page view is an Artificial Page view. | ## pageviews The `pageviews` table contains detailed information about each pageview. | Column Name | Type | Library | Description | | ---------------------------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `event_id` | BIGINT | All | ID of associated pageview event. | | `user_id` | BIGINT | All | Unique ID of associated user, randomly generated by CSQ. | | `session_id` | BIGINT | All | Unique ID of associated session, randomly generated by CSQ. | | `time` | TIMESTAMP | All | Timestamp without time zone of when the pageview occurred. | | `library` | TEXT | All | Version of Contentsquare library which started the session. Can be one of "web" or "iOS". | | `platform` | TEXT | Web | User's operating system. | | `device_type` | TEXT | Web | Device type, which can only be one "Desktop". | | `country` | TEXT | Web | Country in which user session occurred, based on IP. | | `region` | TEXT | Web | Region in which user session occurred, based on IP. | | `city` | TEXT | Web | City in which user session occurred, based on IP. | | `referrer` | TEXT | Web | URL that linked to your site and started the session. If the user navigated directly to your site, or referral headers were stripped, then this value will appear as NULL downstream and as `direct` in the UI. | | `landing_page` | TEXT | Web | URL of the first pageview of the session. | | `browser` | TEXT | Web | User's browser. | | `utm_source` | TEXT | Web | GA-based utm_source tag associated with the session's initial pageview. | | `utm_campaign` | TEXT | Web | GA-based utm_campaign tag associated with the session's initial pageview. | | `utm_medium` | TEXT | Web | GA-based utm_medium tag associated with the session's initial pageview. | | `utm_term` | TEXT | Web | GA-based utm_term tag associated with the session's initial pageview. | | `utm_content` | TEXT | Web | GA-based utm_content tag associated with the session's initial pageview. | | `path` | TEXT | Web | The path of the pageview. | | `query` | TEXT | Web | The query parameters associated with the pageview. | | `hash` | TEXT | Web | The hash parameters associated with the pageview. | | `title` | TEXT | Web | Title of the current page. | | `custom_var` | TEXT | Web | key-value pairs that define more information about the pageview. | | `dynamic_var` | TEXT | Web | key-value pairs that define more information about the session. | | `view_number` | TEXT | Web | The pageview number in the session. | | `is_first` | TEXT | Web | If the page is the entry page then value is 1 otherwise value is 0. | | `is_last` | TEXT | Web | If the page is the exit page then value is 1, otherwise value is 0. | | `scroll_rate` | TEXT | Web | The portion of the page which was displayed (in percentage points). | | `view_duration_msec` | TEXT | Web | Duration between the page view event time (view_time) and the timestamp of the last interaction event (in milliseconds). | | `first_input_delay` | TEXT | Web | Delay (in milliseconds) between the first user interaction and when the web browser can handle it (part of Core Web Vitals). | | `interaction_to_next_paint` | TEXT | Web | Longest visual delay (in milliseconds) experienced by a user when interacting with the page (clicks or keystrokes). | | `time_to_first_byte` | TEXT | Web | Delay (in milliseconds) between the request for the web page and when the web browser received the first piece of data. | | `largest_contentful_paint` | TEXT | Web | Delay (in milliseconds) to render the largest piece of content (part of Core Web Vitals). | | `cumulative_layout_shift` | TEXT | Web | Score about the layout stability of the page rendering (part of Core Web Vitals). | | `dom_interactive_after_msec` | TEXT | Web | The time in milliseconds required before the user is able to interact with the page (although all resources may not be fully loaded yet). | | `fully_loaded` | TEXT | Web | The time in milliseconds required to fully load all the resources of the page, from initiation of the pageview to load completion in the browser. | | `first_contentful_paint` | TEXT | Web | Delay (in milliseconds) to render the first piece of content. | | `start_render` | TEXT | Web | Timestamp sent by tag when the rendering of the page started. | | `window_height` | TEXT | Web | Height of the window in which the page is opened. | | `window_width` | TEXT | Web | Width of the window in which the page is opened. | | `session_replay_link` | TEXT | Web | Contentsquare Platform url link of the session replay. | ## events Contentsquare will create one table for every labeled event you've created within Contentsquare and synced downstream. You currently don't have access to the UI to self-create your event. | Column Name | Type | Libraries | Description | | -------------------- | --------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `event_id` | BIGINT | All | ID of the associated event, randomly generated by CSQ. | | `user_id` | BIGINT | All | Unique ID of the associated user, randomly generated by CSQ. | | `session_id` | BIGINT | All | Unique ID of the associated session, randomly generated by CSQ. | | `pageview_id` | BIGINT | All | Unique ID of the associated page, randomly generated by CSQ. | | `time` | TIMESTAMP | All | Timestamp without time zone of when the event happened. | | `type` | TEXT | All | For web autocaptured events, can be any of view page, click, submit, change, with push state events registered as view page events. For custom events, this will be the custom event name. | | `library` | TEXT | All | Version of Contentsquare library on which event occurred. Can be one of "web", "iOS", or "server". | | `platform` | TEXT | Web | User's operating system. | | `device_type` | TEXT | Web | Device type, which can only be one "Desktop". | | `country` | TEXT | Web | Country in which user session occurred, based on IP. | | `region` | TEXT | Web | Region in which user session occurred, based on IP. | | `city` | TEXT | Web | City in which user session occurred, based on IP. | | `referrer` | TEXT | Web | URL that linked to your site and started the session. If the user navigated directly to your site, or referral headers were stripped, then this value will appear as NULL downstream and as `direct` in the UI. | | `landing_page` | TEXT | Web | URL of the first pageview of the session. | | `landing_page_query` | TEXT | Web | The query parameters of the first page of the user’s session. | | `landing_page_hash` | TEXT | Web | The hash route of the first page of the user’s session. | | `browser` | TEXT | Web | User's browser. | | `utm_source` | TEXT | Web | GA-based utm_source tag associated with the session's initial pageview. | | `utm_campaign` | TEXT | Web | GA-based utm_campaign tag associated with the session's initial pageview. | | `utm_medium` | TEXT | Web | GA-based utm_medium tag associated with the session's initial pageview. | | `utm_term` | TEXT | Web | GA-based utm_term tag associated with the session's initial pageview. | | `utm_content` | TEXT | Web | GA-based utm_content tag associated with the session's initial pageview. | | `domain` | TEXT | Web | Domain including subdomain, e.g. blog.company.io. | | `path` | TEXT | Web | Portion of the current URL following your domain, e.g. /docs for company.io/docs. | | `hash` | TEXT | Web | Portion of the current URL following the hash sign, e.g. #install for company.io/docs#install. | | `query` | TEXT | Web | Query params of the page's current URL, e.g. ?utm_id=1234 for company.io?utm_id=1234. | | `title` | TEXT | Web | Title of the current page. | | `href` | TEXT | Web | href property of link (used for clicks on anchor tags). | | `target_text` | TEXT | Web, iOS | Button text of the event target. | ## `api_errors` The `api_errors` table contains information about API errors detected during user sessions. | Column Name | Type | Library | Description | | ----------------------- | --------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `event_id` | BIGINT | Errors | ID of associated event, randomly generated. | | `user_id` | BIGINT | Errors | ID of associated user, randomly generated. | | `session_id` | BIGINT | Errors | ID of associated session, randomly generated. | | `pageview_id` | BIGINT | Frustration | Unique ID of the associated page, randomly generated by CSQ. | | `time` | TIMESTAMP | Errors | Timestamp without time zone of when the event happened. | | `library` | TEXT | Errors | Version of Contentsquare library which began the session. "web" or "iOS". | | `platform` | TEXT | Errors | User's operating system. | | `device_type` | TEXT | Errors | Device type, which can only be one "Desktop". | | `country` | TEXT | Errors | Country in which user session occurred, based on IP. | | `region` | TEXT | Errors | Region in which user session occurred, based on IP. | | `city` | TEXT | Errors | City in which user session occurred, based on IP. | | `landing_page` | TEXT | Errors | URL of the first pageview of the session. | | `api_error_duration` | TEXT | Errors | Time taken to resolve API error. | | `api_error_endpoint` | TEXT | Errors | URL where API errors are reported. | | `api_error_method` | TEXT | Errors | Standardized communication of API error responses. | | `api_error_status_code` | TEXT | Errors | Numerical code identifying API error. | | `errors_after_clicks` | TEXT | Errors | Issue occurring post-user interaction (boolean). | | `error_group_id` | TEXT | Errors | Identifier for categorizing related errors. | | `error_source` | TEXT | Errors | Origin point of the reported error. | | `type` | TEXT | Errors | API error. | | `referrer` | TEXT | Errors | URL that linked to your site and initiated the session. If the user navigated directly to your site, or referral headers were stripped, then this value will appear as NULL downstream and as `direct` in the UI. | ## `js_errors` The `js_errors` table contains information about JavaScript errors detected during user sessions. | Column Name | Type | Library | Description | | ------------------------ | --------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `event_id` | BIGINT | Errors | ID of associated session event, randomly generated. | | `user_id` | BIGINT | Errors | ID of associated user, randomly generated. | | `session_id` | BIGINT | Errors | ID of associated session, randomly generated. | | `pageview_id` | BIGINT | Frustration | Unique ID of the associated page, randomly generated by CSQ. | | `time` | TIMESTAMP | Errors | Timestamp without time zone of when the event happened. | | `library` | TEXT | Errors | Version of Contentsquare library which began the session. "web" or "iOS". | | `platform` | TEXT | Errors | User's operating system. | | `device_type` | TEXT | Errors | Device type, which can only be one "Desktop". | | `country` | TEXT | Errors | Country in which user session occurred, based on IP. | | `region` | TEXT | Errors | Region in which user session occurred, based on IP. | | `city` | TEXT | Errors | City in which user session occurred, based on IP. | | `landing_page` | TEXT | Errors | URL of the first pageview of the session. | | `error_message` | TEXT | Errors | Description of the encountered error. | | `error_line_number` | TEXT | Errors | Line in the code where the error occurred. | | `js_error_file_name` | TEXT | Errors | File name containing the JavaScript error. | | `js_error_column_number` | TEXT | Errors | Column in the file where the error occurred. | | `errors_after_clicks` | TEXT | Errors | Issue occurring post-user interaction (boolean). | | `error_group_id` | TEXT | Errors | Identifier for categorizing related errors. | | `error_source` | TEXT | Errors | Origin point of the reported error. | | `type` | TEXT | Errors | JS error. | | `referrer` | TEXT | Errors | URL that linked to your site and initiated the session. If the user navigated directly to your site, or referral headers were stripped, then this value will appear as NULL downstream and as `direct` in the UI. | ## `custom_errors` The `custom_errors` table contains information about custom errors detected during user sessions. | Column Name | Type | Library | Description | | --------------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `event_id` | BIGINT | Error | ID of associated session event, randomly generated. | | `user_id` | BIGINT | Error | ID of associated user, randomly generated. | | `session_id` | BIGINT | Error | ID of associated session, randomly generated. | | `pageview_id` | BIGINT | Error | Unique ID of the associated page, randomly generated by CSQ. | | `time` | TIMESTAMP | Error | Timestamp without time zone of when the event happened. | | `library` | TEXT | Error | Version of Contentsquare library which began the session. "web" or "iOS". | | `platform` | TEXT | Error | User's operating system. | | `device_type` | TEXT | Error | Device type, which can only be one "Desktop". | | `country` | TEXT | Error | Country in which user session occurred, based on IP. | | `region` | TEXT | Error | Region in which user session occurred, based on IP. | | `city` | TEXT | Error | City in which user session occurred, based on IP. | | `landing_page` | TEXT | Error | URL of the first pageview of the session. | | `error_message` | TEXT | Error | Description of the encountered error. | | `errors_after_clicks` | TEXT | Error | Issue occurring post-user interaction (boolean). | | `error_group_id` | TEXT | Error | Identifier for categorizing related errors. | | `error_source` | TEXT | Error | Origin point of the reported error. | | `type` | TEXT | Error | Custom Error. | | `referrer` | TEXT | Error | URL that linked to your site and initiated the session. If the user navigated directly to your site, or referral headers were stripped, then this value will appear as NULL downstream and as `direct` in the UI. | ## `frustration_factors` The following data schema table will be the same for every frustration factor (rage click, excessive hovering, multiple use element, multiple field interactions, multiple button interactions, loading time high and low activity). | Column Name | Type | Library | Description | | ------------------- | --------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `event_id` | BIGINT | Frustration | ID of the associated event, randomly generated by Contentsquare. | | `user_id` | BIGINT | Frustration | Unique ID of the associated user, randomly generated by Contentsquare. | | `session_id` | BIGINT | Frustration | Unique ID of the associated session, randomly generated by Contentsquare. | | `pageview_id` | BIGINT | Frustration | Unique ID of the associated page, randomly generated by Contentsquare. | | `time` | TIMESTAMP | Frustration | Timestamp without time zone of when the event happened. | | `library` | TEXT | Frustration | Frustration | | `platform` | TEXT | Frustration | User's operating system. | | `device_type` | TEXT | Frustration | Device type, which can only be one "Desktop". | | `country` | TEXT | Frustration | Country in which user session occurred, based on IP. | | `region` | TEXT | Frustration | Region in which user session occurred, based on IP. | | `city` | TEXT | Frustration | City in which user session occurred, based on IP. | | `landing_page` | TEXT | Frustration | URL of the first pageview of the session. | | `type` | TEXT | Frustration | rage click | | `referrer` | TEXT | Frustration | URL that linked to your site and initiated the session. If the user navigated directly to your site, or referral headers were stripped, then this value will appear as NULL downstream and as `direct` in the UI. | | `domain` | TEXT | Frustration | Domain including subdomain, e.g. http://blog.company.io. | | `path` | TEXT | Frustration | Portion of the current URL following your domain, e.g. /docs for company.io/docs. | | `hash` | TEXT | Frustration | Portion of the current URL following the hash sign, e.g. #install for company.io/docs#install. | | `query` | TEXT | Frustration | Query params of the page's current URL, e.g. ?utm_id=1234 for http://company.io?utm_id=1234. | | `target_text` | TEXT | Frustration | The text displayed on the button clicked. | | `frustration_score` | TEXT | Frustration | Frustration score of the pageview. | | `target_path` | TEXT | Frustration | Target path of the HTML component where the event happens. | | `relative_time` | INT | Frustration | The point in time when the event happens. | | `value` | INT | Frustration | The number of clicks. | ## `ecommerce_transactions` The `ecommerce_transactions` table contains information about e-commerce transactions. | Column Name | Type | Library | Description | | ---------------------- | --------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `event_id` | BIGINT | Contentsquare | ID of associated session event, randomly generated. | | `user_id` | BIGINT | Contentsquare | ID of associated user, randomly generated. | | `session_id` | BIGINT | Contentsquare | ID of associated session, randomly generated. | | `time` | TIMESTAMP | Contentsquare | Timestamp without time zone of when the pageview occurred. | | `library` | TEXT | Contentsquare | Version of Contentsquare library which began the session. "web" or "iOS". | | `platform` | TEXT | Contentsquare | User's operating system. | | `country` | TEXT | Contentsquare | Country in which user session occurred, based on IP. | | `region` | TEXT | Contentsquare | Region in which user session occurred, based on IP. | | `city` | TEXT | Contentsquare | City in which user session occurred, based on IP. | | `referrer` | TEXT | Contentsquare | URL that linked to your site and initiated the session. If the user navigated directly to your site, or referral headers were stripped, then this value will appear as NULL downstream and as `direct` in the UI. | | `type` | TEXT | Contentsquare | E-commerce transaction. | | `device_type` | TEXT | Contentsquare | Device type, which can only be one "Desktop". | | `transaction_amount` | TEXT | Contentsquare | The total monetary value of a purchase or payment made by a user during a session. | | `transaction_currency` | TEXT | Contentsquare | The currency in which the transaction amount was processed. | ## `all_events` Table Does Not Sync For S3. The `all_events` table does not sync for S3. You can create an `all_events` view of all synced tables after the data synced to S3 has gone through ETL processing. | Column Name | Type | Description | | ------------------ | --------- | --------------------------------------------------------------------- | | `event_id` | BIGINT | ID of associated event, randomly generated by Contentsquare. | | `user_id` | BIGINT | Unique ID of associated user, randomly generated by Contentsquare. | | `session_id` | BIGINT | Unique ID of associated session, randomly generated by Contentsquare. | | `time` | TIMESTAMP | Timestamp without time zone of when event happened. | | `event_table_name` | TEXT | Name of the table where similar events can be found. | :::warning[BigQuery Limitations] In most cases, the schema for the `all_events` view will consist of the union of all columns from all event tables, with nulls filled in where applicable. However, if you are syncing many tables to your project, this can run into BigQuery query length limits, in which case we'll fall back to one of the following reduced column sets: - All built-in Contentsquare columns that is `event_view_name` and columns contained in the pageviews/sessions tables - Basic columns - `event_view_name`, `user_id`, `event_id`, `session_id`, time If your `all_events` view is created with a reduced column set, you can join it with the underlying event views to access any property columns that are not available in the view. ::: ## `_sync_history` Contentsquare creates a table called `_sync_history` that contains a record for every attempted sync. This table is helpful for monitoring sync performance and scheduling dependent jobs. All timestamps are in UTC for Redshift and BigQuery and in local time for Snowflake. | Column Name | Type | Description | | ------------------------ | --------- | ------------------------------------------------------------------------------------------------- | | `status` | STRING | Takes value running/succeeded/failed based on the outcome of the sync attempt. | | `start_time` | TIMESTAMP | Start time of the sync attempt. | | `finish_time` | TIMESTAMP | Finish time of the sync attempt. | | `error` | STRING | Error message if sync fails. | | `next_scheduled_sync_at` | TIMESTAMP | Time of the next scheduled sync (estimated at the time of sync based on sync frequency settings). | ## `_sync_info` Contentsquare creates a table called `_sync_info` that contains metadata around the sync process and last updated times. | Column Name | Type | Description | | -------------------- | --------- | ------------------------------------------------------------------ | | `event_table_name` | TEXT | The event name. | | `sync_started` | TIMESTAMP | A timestamp for when that table began syncing. | | `sync_ended` | TIMESTAMP | A timestamp for when that table completed syncing. | | `synced_to_time` | TIMESTAMP | A timestamp that reflects the most recent occurrence of the event. | | `inserted_row_count` | BIGINT | The number of rows inserted during the most recent sync. | ## `user_migrations` When a user is identified, a migration occurs to aggregate the data under the new identity. These migrations are recorded in this table. Time is a column for Redshift and S3 destinations only. Snowflake and BigQuery do not have a column for time. | Column Name | Type | Description | | -------------- | --------- | -------------------------------------------- | | `from_user_id` | BIGINT | The migrating user's ID. | | `to_user_id` | BIGINT | The destination user's ID. | | `time` | TIMESTAMP | A timestamp for when the migration occurred. | ## `event_metadata` This table contains metadata about the names of events, which allows you to build automated jobs that use this metadata. This table is re-created on each sync to stay updated with the latest event metadata. | Column Name | Type | Description | | ----------------- | --------- | ----------------------------------------------------------------------------------------------------------------------- | | `table_name` | TEXT | For each event, this row contains the sanitized name of the table containing the event's data synced to your warehouse. | | `ui_name` | TEXT | For each event, this row contains the name of the event in Contentsquare. | | `last_updated_at` | TIMESTAMP | Time event label was last updated. | | `last_updated_by` | TEXT | User who last updated event label. | | `notes` | TEXT | Notes attached to the event. | | `source` | TEXT | Data capture source (ex: web, ios, android). | | `verified_at` | TIMESTAMP | Time event was verified. | | `verified_by` | TEXT | User who verified the event. | The `event_metadata` table shows up differently for S3. You can query it as follows: ```json { "ui_name": "Stripe charge", "table_name": "stripe_charge", "source": "stripe", "last_updated_at": "1609459200000", "last_updated_by": "sales@contentsquare.com", "notes": "This is a note", "verified_at": "1640995200000", "verified_by": "admin@contentsquare.com" } ``` --- # Databricks URL: https://docs.contentsquare.com/en/connect/databricks/ Databricks is a unified analytics platform built on Apache Spark that combines data engineering, data science, and analytics workloads. The Data Connect integration allows you to automatically sync your Contentsquare data to Databricks for advanced analysis and machine learning. ## Prerequisites Before setting up the Databricks integration, ensure you have: - Access to an **AWS-hosted Databricks** account that uses the **Unity Catalog** ## Configure Data Connect :::warning[Admin only] Configuration of this destination is only available to admin users in Contentsquare. ::: 1. Log in to Contentsquare. 1. Navigate to **Analysis setup** > **Data Connect**. 1. Select **Connect** next to Databricks. 1. Provide the following information: - **Hostname**: The ID of your Databricks account, which you can find in the account URL. - **Path**: The path of the warehouse you are connecting via this integration. - **Catalog**: The catalog that this data should sync to; if left blank, this integration will create a new catalog. - **Schema (optional)**: The schema that this data should sync to; if left blank, this integration will create a new schema. - **Token**: This is required to allow Data Connect to write to the schema. The token must be a Personal Access Token (PAT) rather than an OAuth Token. 1. Select **Next**. Once setup is complete, you’ll see a sync within 24 hours with the following built-in tables: - Pageviews - Sessions - Users - `user_migrations` You can create an `all_events` view to Databricks by setting up a query like this one: ```sql SELECT event_id, time, user_id, session_id, 'test_event_table' AS event_table_name FROM "TEST_DB"."TEST_SCHEMA"."TEST_EVENT_TABLE" UNION SELECT event_id, time, user_id, session_id, 'click_event_table' AS event_table_name FROM "SCHEMA"."CLICK_EVENT_TABLE" UNION SELECT event_id, time, user_id, session_id, 'pageview_event_table' AS event_table_name FROM "SCHEMA"."PAGEVIEW_EVENT_TABLE" ``` ## Limitations - Segments syncing is not supported during beta. --- # Managing Data Syncing URL: https://docs.contentsquare.com/en/connect/managing-data-syncing/ This guide explains how Data Connect syncs data to your data warehouse and how to effectively manage this process. ## Sync Process Overview Data Connect uses a reliable ETL (Extract, Transform, Load) process to move data from Contentsquare to your data warehouse. Understanding this process helps you effectively manage your data pipeline and troubleshoot any issues. ## Sync Frequency Ò Data Connect offers different sync frequency options depending on your plan: - **Daily Sync**: All plans include daily data syncs - **Hourly Sync**: Enterprise plans can enable hourly syncs for more frequent data updates - **Custom Schedules**: Enterprise plans can work with Contentsquare to establish custom sync schedules The sync frequency affects how current your data is in the warehouse. More frequent syncs provide fresher data but may increase warehouse compute costs. ## Initial Sync vs. Incremental Updates Data Connect uses two types of data syncs: ### Initial Sync When you first set up Data Connect or add a new table, an initial sync copies all historical data from Contentsquare to your warehouse. This process: - Creates the necessary tables and views - Copies all historical data - May take several hours to days depending on data volume - Runs only once per table (unless a full resync is needed) ### Incremental Updates After the initial sync, Data Connect performs incremental updates during each sync window. These updates: - Only transfer new or changed data since the last sync - Are much faster than initial syncs - Maintain data consistency while minimizing warehouse load - Run on your configured schedule (daily, hourly, etc.) ## Monitoring Sync Status You can monitor the status of your Data Connect syncs through: - The Data Connect dashboard in the Contentsquare UI - Email notifications for failed syncs (if configured) - Warehouse query logs showing Data Connect activity It's good practice to regularly verify that syncs are completing successfully, especially after making changes to your Contentsquare implementation. ## Managing Schema Changes As your Contentsquare implementation evolves (adding new events or properties), Data Connect handles schema evolution automatically: ### How Schema Changes Are Handled - **New Property Added**: A new column is added to the appropriate table - **New Event Defined**: A new table is created for the event - **Property Type Change**: Handled according to warehouse-specific rules ### Potential Issues Some schema changes may require special handling: - **Column Name Conflicts**: If you rename properties in Contentsquare to match existing columns - **Type Incompatibilities**: If property values change in ways that conflict with existing column types - **Reserved Words**: If new properties use names that are reserved in your warehouse ## Sync Failure Handling If a Connect sync fails: 1. Contentsquare's system will automatically retry the sync 1. If multiple retries fail, you'll receive a notification 1. Contentsquare's support team can help diagnose and resolve the issue 1. Once resolved, syncs will resume from where they left off ## Data Retention and Historical Data Data Connect syncs all data available in your Contentsquare account based on your data retention settings: - Data retention periods are set at the Contentsquare account level - Deleted data in Contentsquare will not be removed from your warehouse automatically - If you need to remove data from your warehouse, you'll need to do so manually ## Best Practices To ensure smooth operation of your Data Connect pipeline: 1. **Monitor sync status regularly**: Check that syncs are completing successfully 1. **Plan for schema changes**: Consider potential impacts when adding new properties 1. **Test new warehouse queries**: Verify queries after schema changes 1. **Manage warehouse resources**: Schedule heavy queries outside of sync windows 1. **Document custom tables**: Maintain documentation for any views or derived tables you create 1.. **Set up alerting**: Configure monitoring for sync failures 1. **Manage data volume**: Archive or partition historical data as needed ## Troubleshooting If you encounter issues with your Data Connect syncs: 1. Check for error messages in the Data Connect dashboard 1. Verify warehouse permissions and quotas 1. Look for schema conflicts 1. Review recent changes to your Contentsquare implementation 1. Contact Contentsquare support with specific error messages and timestamps For detailed answers to common sync issues, see the [Troubleshooting FAQs](/en/connect/troubleshooting-faqs/) guide. --- # Redshift URL: https://docs.contentsquare.com/en/connect/redshift/ Amazon Redshift is a fully managed, petabyte-scale data warehouse service in the cloud. The Data Connect integration with Redshift allows you to automatically sync your Contentsquare data to Redshift for advanced analysis and joining with other business data. ## Prerequisites Before setting up the Redshift integration, ensure you have: - **An Amazon Redshift cluster** that is provisioned and accessible - **Sufficient permissions** to create schemas and tables in Redshift - **Database credentials** with appropriate permissions ## Redshift Setup 1. Ensure your Redshift cluster is running and accessible 1. Create a dedicated schema for Contentsquare data (recommended): ```sql CREATE SCHEMA heap_data; ``` 1. Create a dedicated user for Data Connect (optional but recommended): ```sql CREATE USER heap_connect_user WITH PASSWORD 'your-secure-password'; GRANT USAGE ON SCHEMA heap_data TO heap_connect_user; GRANT CREATE ON SCHEMA heap_data TO heap_connect_user; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA heap_data TO heap_connect_user; ALTER DEFAULT PRIVILEGES IN SCHEMA heap_data GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO heap_connect_user; ``` 1. Ensure your Redshift cluster is accessible from Contentsquare's servers: - If your cluster is public, ensure the security group allows access - If your cluster is private, you may need to set up VPC peering or a VPN connection ## Configure Data Connect :::warning[Admin only] Configuration of this destination is only available to admin users in Contentsquare. ::: 1. Log in to Contentsquare. 1. Navigate to **Analysis setup** > **Data Connect**. 1. Select **Connect** next to Redshift. 1. Enter the required information: - Host (endpoint) - Port (typically 5439) - Database name - Username - Password - Schema (the schema you created for Contentsquare data) 1. Select **Connect**. --- # Data Connect URL: https://docs.contentsquare.com/en/connect/ import { Badge } from "~/components"; Data Connect is built for data teams to sync Contentsquare behavioral data to their warehouse, without the hassle of manual data wrangling. All exports are completely retroactive from the date of activation. It makes it seamless to combine Contentsquare with other sources and power use cases like journey optimization, personalization, churn prediction, retargeting, AI/ML training.
Marketing automation
Identify high-intent users who didn't convert like rage clickers or cart abandoners, and trigger marketing campaigns to re-engage them.
A/B testing and personalization
Export session data into a warehouse. Sync user frustration segments with A/B testing tools and prioritize high-impact test ideas in an A/B testing platform.
Power predictive models
Fuel AI and machine learning models with your Contentsquare data to predict churn, forecast conversion, and detect anomalies.
BI Tools / C-Level Dashboard
BI dashboards with digital experience data — gives teams and more importantly executives a unified view of business and user behavior metrics helping them understand not just what happened, but why.
--- # Snowflake URL: https://docs.contentsquare.com/en/connect/snowflake/ Snowflake is a cloud-based data platform that provides data warehouse-as-a-service designed for the cloud. The Data Connect integration with Snowflake allows you to automatically sync your Contentsquare data to Snowflake for advanced analysis and joining with other business data. ## Prerequisites Before setting up the Snowflake integration, ensure you have: - **A Snowflake account** with appropriate access - **Sufficient permissions** to create databases, schemas, and tables - **Snowflake user credentials** with appropriate roles ## Snowflake setup To get started, you need to have the following information about your Snowflake account: - **Your Snowflake account name**: Your account name can be found in the URL used to access Snowflake `.snowflakecomputing.com`. - **Your account region**: We currently support the following regions: **AWS**: - us-west-2 (Oregon): region not included in snowflake URLs for this region only - us-east-1 (N. Virginia) - us-east-2 (Ohio) - eu-west-1 (Ireland) - eu-central-1 (Frankfurt) - ap-southeast-2 (Sydney) - ca-central-1 (Canada Central) **Azure**: - east-us-2 (Virginia) - west-us-2 (Washington) - canada-central (Toronto) - west-europe (Netherlands) - australia-east (New South Wales) - north-europe (Ireland) - centralus (Iowa) - uksouth (London) **GCP**: - us-central1 (Iowa) - europe-west4 (Netherlands) If you are outside of these regions, let us know and we will work to add support for you. To find this information in your Snowflake account, see the **Analysis Setup** > **Connect** > **Snowflake** page in Contentsquare. This page will only be available once Data Connect has been enabled for you by someone on our end. ## Configure Data Connect :::warning[Admin only] Configuration of this destination is only available to admin users in Contentsquare. ::: 1. Log in to Contentsquare. 1. Navigate to **Analysis setup** > **Data Connect**. 1. Select **Connect** next to Snowflake. 1. Create a database in Snowflake by copying and running the generated snippet. 1. Select **Next**. 1. Enter your Snowflake hostname. 1. Select **Connect**. --- # Troubleshooting FAQs URL: https://docs.contentsquare.com/en/connect/troubleshooting-faqs/ This guide answers common troubleshooting questions for Connect and provides solutions to the most frequent issues. ## Your tool ingests data into our Data Warehouse — does it also delete it? If so, what is the data retention period? Yes, our system does perform deletions in a few specific scenarios: - **GDPR Deletion Requests**: When we receive a GDPR deletion request, we automatically propagate that deletion to the customer’s data in their warehouse to ensure compliance. - **Duplicate Row Cleanup**: During the data loading process, we may remove duplicate rows in order to maintain data quality and consistency. - **Property unsync via App UI**: If a customer disables or unsyncs a property in the App UI, we treat this as a bulk deletion and drop the corresponding column from the dataset. This functionality is not currently available for DXA Connect customers. These mechanisms ensure that data remains accurate, compliant, and aligned with customer configurations. For data retention, we never apply data retention on data in our customers warehouses. ## How regularly is the data refreshed in the destination warehouse? (Frequency of Update) Sync every 24h by default. Intraday syncing will be available after GA (H2 2026). ## What's the volume of data that I can expect to see in the syncs? - Daily volume ≈ your daily volume fire-hose. - Users = Count of Net New Users for last 24 hours - Sessions = Count of Unique User Sessions for last 24 hours - Pageviews = Count of Unique Pageviews for last 24 hours - The `_sync_info.inserted_row_count column` gives an exact per-table delta after every run, so you can chart growth and cost. See [Data Schema](../data-schema/) ## How the data is transmitted from your systems to our Data Warehouse. Is it encoded? Encrypted? HTTPS? All traffic is encrypted (TLS 1.2+); objects are encrypted at rest by the cloud providers. | Warehouse | Transport path CS → Destination | Encryption in transit | Encryption at rest | | --------------- | ---------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | | Google BigQuery | HTTPS calls from CS app servers (official BigQuery client). Optional file-staging: S3 ➜ GCS ➜ BigQuery LOAD job. | [TLS 1.2+ on every BigQuery and GCS endpoint.](https://cloud.google.com/docs/security/encryption-in-transit) | All content encrypted with AES-256; CMEK/CSEK optional | | Snowflake | No file copy. CS is the _provider_ and shares a database; your Snowflake account reads it over Snowflake’s front door. | [All Snowflake interfaces enforce TLS 1.2+](https://docs.snowflake.com/en/release-notes/bcr-bundles/un-bundled/bcr-1727) | Persistent storage encrypted end-to-end (E2EE, AES-256) by default; CMK available | | Amazon Redshift | Contentsquare JDBC/ODBC client connects to the cluster endpoint. Optional SSH tunnel supported. | SSL/TLS required on the leader node; ACM-issued certs; SSH tunnel adds an extra layer [AWS docs](https://docs.aws.amazon.com/redshift/latest/mgmt/security-encryption-in-transit.html); See [Redshift](../redshift/) | Cluster data encrypted with KMS or HSM keys (AES-256) | | Amazon S3 | Contentsquare writes Avro files over HTTPS to the bucket you specify; you then ETL into anything. | [TLS/SSL on every PUT/GET request](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingEncryption.html) | All new objects are automatically AES-256-encrypted; SSE-KMS or SSE-S3 selectable | | Databricks | Contentsquare posts to the Databricks REST/SQL API at port 443 with a Personal Access Token. | [All egress traffic requires TLS 1.2+](https://docs.databricks.com/aws/en/security/privacy/security-profile) | Workspace storage and S3 backing objects encrypted with AES-256; CMK option for S3 | ## How does Contentsquare send SQL queries to BigQuery? CS retrieves the service-account key you supplied, instantiates the official BigQuery client library, and issues SQL INSERT/UPDATE statements over HTTPS. The TLS connection (TLS 1.2+) encrypts the queries in transit. ## Why is an extra file-copy step required? BigQuery will only load data files that already reside in Google Cloud Storage (GCS). Contentsquare therefore copies the export files from its Amazon S3 bucket into a GCS bucket before triggering the load job. ## Can the GCS bucket live inside my own VPC? Yes. Provide a GCS path that sits in your VPC and CS will stage the files there, keeping the entire transfer inside your GCP network. If you prefer not to manage a bucket, CS uses a GCS bucket in its VPC. ## How is the load into BigQuery started? Contentsquare calls jobs.insert through the same BigQuery client to create a “LOAD” job that ingests the staged files into your dataset. ## What happens after the files are in GCS—how does Contentsquare get them into BigQuery and is that transfer secure? Contentsquare calls **jobs.insert** through the BigQuery client library with a load configuration that points to the staged files. BigQuery’s service tier then **pulls the objects straight out of Cloud Storage across Google’s private backbone, using Application-Layer Transport Security (ALTS) for mutual authentication and encryption**. The data never leaves Google’s internal network, and the objects remain encrypted at rest in GCS until the job finishes. ## Is the file-transfer path secure? All HTTPS traffic is encrypted with TLS, and Google encrypts objects at rest in GCS. The internal GCS → BigQuery load runs on Google’s private backbone, also encrypted and authenticated. ## Can we authenticate BigQuery with our own service account rather than Contentsquare’s? Yes. We can switch the connector to your service account. ### How to hand it off 1. Create a dedicated service account for CS and enable BigQuery + Cloud Storage APIs. 2. Grant it the minimum roles: - **BigQuery Data Editor** on the target dataset - **Storage Object Admin** on the GCS staging bucket 3. Send Contentsquare: - the service-account email - JSON key file (private key) GCS bucket name for staging 4. CS updates your integration to use that key; after the next sync the CS-owned service account is no longer used. All subsequent file copies and load jobs run entirely under your credentials, giving you full audit visibility and revocation control. ## How does Data Connect export differ from the GA4 → BigQuery? GA4 delivers one nested **events_YYYYMMDD** table/day; every hit sits in an `event_params` array and device fields. CS Connect outputs **flat, session- or page-level rows** with > 200 Experience Analytics and Error metrics (scroll depth, rage-click flags, JS errors, Core Web Vitals, etc.) and optional cvar/dvar columns. That relational shape avoids the UNNEST work GA4 requires and lets you retrofit new UX metrics without a schema change. ## Privacy — does the export contain Personal Data? By default the tag masks or hashes fields that could hold Personal Data (e-mail, full IP, names, card numbers). ## Can we pull files from an endpoint instead of letting CS write into our DWH? Yes. Use the [**Raw Data API**](/en/api/export/): create a job, then download the gzip-compressed JSON/CSV files over HTTPS and load them yourself. ## Does Connect support Workload Identity Federation instead of a key file? Not yet. Current integrations authenticate with a JSON key for a service account that you control. Google’s WIF endpoints are on our security backlog; earliest ETA is Q4 2025. ([General WIF overview](https://cloud.google.com/iam/docs/workload-identity-federation?utm_source=chatgpt.com) ) ## Does Data Connect support both exporting data to a data warehouse and importing data from a data warehouse into Contentsquare? Data Connect is a _Data Out_ solution only. It enables customers to sync data from Contentsquare (CSQ) to their data warehouse, but it does **not** support importing data back into CSQ. To enrich sessions within CSQ (_Data In_), customers can use existing capabilities such as integrations (for example A/B testing tools, VoC platforms, analytics tools) and variables (custom or dynamic). This enriched data can then be included in the export via Data Connect. ## Does DXA Connect replicate data into Contentsquare’s Snowflake before sending it to the customer’s Snowflake? Yes. Data is first replicated from our platform into Connect’s Snowflake account. From there, we use [Snowflake’s secure data sharing](https://docs.snowflake.com/en/user-guide/data-sharing-intro) to give customers access to the relevant tables and views within their own Snowflake account. ## Where is Connect’s Snowflake instance hosted? The Connect Snowflake account is hosted in the **same region as the customer's selected Snowflake destination**. **Example:** If the customer’s destination is in **AWS eu-west-1 (EU Ireland)**, the data is replicated into a Connect Snowflake account in **AWS eu-west-1**, then shared with the customer. ## Is the Snowflake region the same for Contentsquare Connect and DXA Connect? Yes. Both products replicate data into a Snowflake region based on the customer’s selected destination. The data is then securely shared with the customer using the same underlying platform. ## Did Contentsquare Connect customers get read-only access to data in Contentsquare’s Snowflake? Yes, we share the data into the customers account via [Snowflake’s secure data sharing](https://docs.snowflake.com/en/user-guide/data-sharing-intro). ## Will DXA Connect customers have access to the Contentsquare-hosted Snowflake? No, we no longer offer the Contentsquare-hosted Snowflake service to new customers. Customers must have their own Snowflake account, which can be created by [Sign Up for Snowflake](https://signup.snowflake.com/) ## Do we need to disclose the location of Contentsquare’s Snowflake to customers? No. The location always aligns with the region selected by the customer for their Snowflake destination. ## Are there any limitations on the Snowflake regions supported by Connect? Yes. Not all Snowflake regions are currently supported**.** A list of supported regions is available here: On the Contentsquare’s [help docs](https://help.Contentsquare.io/hc/en-us/articles/18700055120284-Snowflake-Integration#requirements). If a customer needs a region not currently supported, a feature request can be submitted via Airfocus. ## Are there architectural or data access differences between Contentsquare Connect and DXA Connect? No. Both use the same platform architecture and data access mechanisms. The only difference is that Contentsquare-hosted Snowflake is no longer being sold, even though some legacy customers still use it. --- # Error Analysis URL: https://docs.contentsquare.com/en/webview-tracking-tag/error-analysis/ Contentsquare allows you to collect similar error types as in a web project: JS errors, API errors and Custom errors. ## WebView error tracking prerequisites In order to collect WebView errors, Error Analysis needs to be set up on the native side. See the dedicated documentation: [iOS](/en/ios/error-analysis/) and [Android](/en/android/error-analysis/). ## How WebView error tracking works Similar to analytics events and Session Replay, once set in WebView mode, the web tracking tag will collect errors and pass them to the native SDK, which will then send them to the dedicated Apps project. Each error type has a collection setting that needs to be enabled by your Contentsquare Implementation manager. ## JS errors Similar to web context, JS errors are collected out of the box if the collection is enabled in the web project associated with the tracking tag loaded in the page. Find more information on how Contentsquare handles JS errors in our [JavaScript errors Help Center article](https://support.contentsquare.com/hc/en-us/articles/360014703659). ## API errors Similar to web context, API errors are collected out of the box if the collection is enabled in the web project associated with the tracking tag loaded in the page. Find more information on how Contentsquare handles API errors in our [Analyzing API errors Help Center article](https://support.contentsquare.com/hc/en-us/articles/360019857800). ### Removing Personal Data in request URL path By default, the API errors feature collects the URL path of the failed API requests. To prevent the collection of Personal Data in the URL path, you can rewrite the request URL path. Follow the web documentation dedicated section: [Removing Personal Data in API errors](/en/web/personal-data-handling/#removing-personal-data-in-api-errors). ### API Troubleshooting Details :::note This is an on-demand feature. Reach out to your Contentsquare contact to enable it. ::: API errors troubleshooting details enables you to collect more information about API errors so you can troubleshoot errors faster. With this feature you will be able to see three types of additional API error details in the Event Stream of Session Replay. - The HTTP headers of the request and the response. - The body (the data sent by the request or received in the response). - The query parameters for the URL of the requested endpoint. #### Where to configure API troubleshooting details Similar to the collection settings, the Tag loaded in WebView mode will apply the API troubleshooting details rules inherited from the configuration defined in the associated web project. See [API Troubleshooting Details](https://support.contentsquare.com/hc/en-us/articles/6553281476124) for more details. :::warning The encryption used for WebView API errors will be the one from the mobile project. ::: ## Custom errors Follow the web documentation section to implement custom error collection: [Sending custom errors](/en/web/sending-custom-errors/). Find more information on how Contentsquare handles Custom errors in our [Custom errors Help Center article](https://support.contentsquare.com/hc/en-us/articles/5584481982364). ## Validate WebViews error collection If in-app features are enabled, you will be able to see the WebView errors collected as events in the SDK Logs and Log Visualizer. See [iOS Debugging and Logging](/en/ios/in-app-features/#debugging-and-logging) and [Android Debugging and Logging](/en/android/in-app-features/#debugging-and-logging) sections for more details about debugging and logging. ### WebView errors in SDK Logs Check out SDK logs to validate WebView errors are properly collected: ```kotlin CSLIB: API Error (from WebView) - GET 401 https://api.client.com CSLIB: JS Error (from WebView) - - CSLIB: Custom Error (from WebView): - Attributes: [key:value, key:value...] ``` ```swift CSLIB ℹ️ Info: API Error (from WebView) - GET 401 https://api.client.com CSLIB ℹ️ Info: JS Error (from WebView) - - CSLIB ℹ️ Info: Custom Error (from WebView): - Attributes: [key:value, key:value...] ``` ### WebView errors in Log Visualizer Use [Log Visualizer](https://support.contentsquare.com/hc/en-us/articles/4408408544530) from the Experience Analytics project to validate WebView errors are properly collected and received. --- # Collected Data URL: https://docs.contentsquare.com/en/webview-tracking-tag/collected-data/ Once communication is established, the tag will start tracking the following events and pass them over to the SDK: - **Pageviews** manually triggered (with the dedicated command) - **Transactions** manually triggered (with the dedicated command) - **Dynamic variables** manually triggered (with the dedicated command) - **Gestures** automatically detected: _tap, long press, scrolls and swipes (with finger direction)_ - **HTML DOM** and **DOM Mutation** when Session Replay is activated - **HTML DOM** when a snapshot of the screen is triggered by the SDK _(see Enable Snapshot Mode in iOS and Android docs)_. --- # Migration from the legacy WebView Tracking Tag URL: https://docs.contentsquare.com/en/webview-tracking-tag/migrate-from-the-legacy-tag/ To migrate from the legacy WebView Tracking Tag to the latest, follow these steps: 1. **Update the Tag** ```javascript del={6, 8} ins={3, 5} ``` `YOUR_TAG_ID` refers either to a new project or an existing Web project. 1. **Update pageview tracking** ```javascript del={1} ins={2} window.cs_wvt.push(["trackPageview", "My Custom Page Title"]); window._uxa.push(["trackPageview", "My Custom Page Title"]); ``` 📚 See [`trackPageview`](/en/web/command-reference/#trackpageview). 1. **Update the tracking of transactions** ```javascript del={1-2} ins={3-4, 8} window.cs_wvt.push([ "trackTransaction", window._uxa.push([ "ec:transaction:create", { value: 1000, currency: "EUR", id: "my-transaction-id" }, ]); window._uxa.push(["ec:transaction:send"]); ``` 📚 See [`ec:transaction:create`](/en/web/command-reference/#ectransactioncreate) and [`ec:transaction:send`](/en/web/command-reference/#ectransactionsend). 1. **Update the dynamic variable tracking** ```javascript del={1} ins={2} window.cs_wvt.push(["trackDynamicVariable", window._uxa.push(["trackDynamicVariable", { key: "AB_ABT_Label_Best_Price_PC", value: "With best price" }, ]); ``` 📚 See [`trackDynamicVariable`](/en/web/command-reference/#trackdynamicvariable). --- # Privacy URL: https://docs.contentsquare.com/en/webview-tracking-tag/privacy/ ## Handling User Consent :::tip[Collecting user consent] By default, user consent should be handled through the SDK. If your application context requires to collect user consent from the WebView, follow the instructions below. ::: Our mobile SDK considers every new user to be opted-out by default. You are responsible for creating the UI asking users for their consent and allowing them to manage their privacy settings and then calling the appropriate Contentsquare following methods (`optin` or `opt-out`). If you think securing user consent is not required for your app, discuss it during the implementation process with your main Contentsquare contact. ## Opt-in :::note This command is available starting with iOS SDK `4.13.0`, Android SDK `4.10.0`, Flutter plugin `2.3.0`, React Native Bridge `3.0.0`. ::: Use the Opt-in API to get user consent. Calling this API generates a user ID and initiates tracking. ```javascript {2} window._uxa = window._uxa || []; window._uxa.push(["optin"]); ``` ## Opt-Out :::note This command is available starting with iOS SDK `4.13.0`, Android SDK `4.10.0`, Flutter plugin `2.3.0`, React Native Bridge `3.0.0`. ::: When this API is called, tracking stops immediately, all settings are reset (Session number, Page number...) and all files and directories regarding Contentsquare are deleted. This means that the user ID is deleted. The SDK will never track or collect any data from the user's phone unless the Opt-in API is called again. ```javascript {2} window._uxa = window._uxa || []; window._uxa.push(["optout"]); ``` --- # WebView Tracking URL: https://docs.contentsquare.com/en/webview-tracking-tag/ ## Introduction To track WebViews in your app using Contentsquare, you'll need to configure the tracking tag and the mobile SDK to work together. ## Context ### Your page is only accessible from WebView This means you only display the webpage in your mobile app using a WebView. The mobile SDK will automatically inject the tracking tag into the WebView. You only need to track the WebView through the mobile code, and you're all set! Below are the implementation guides for each platform: - 📚 [iOS](/en/ios/track-webviews/) - 📚 [Android](/en/android/track-webviews/) - 📚 [Flutter](/en/flutter/track-webviews/) - 📚 [React Native](/en/react-native/track-webviews/) :::note The automatic tag injection is available from SDK versions iOS 4.35.1, Android 4.31.0, Flutter plugin 3.13.0, and React Native bridge 4.8.0. If your installation doesn't meet this requirement, you need to configure the tracking as described below. ::: ### Your page is accessible from WebView and web This means you use Contentsquare to track the same webpage on both your website and your mobile app within a WebView. The tracking tag needs to be configured based on whether the webpage is running in a WebView or a standard web context. ## Tracking tag configuration We support implementing the **tracking tag** via [Google Tag Manager](#google-tag-manager-template) or [manually](#manual-injection). Note that GTM is the preferred method of injection of the Contentsquare Tag. :::warning[Required trackpageview call] You **must** include a `trackPageview` command in your tag code. This call is essential to initialize and start the tracking process in WebView environments. Without this command, tracking will not function properly. ::: ## The trackPageview command The `trackPageview` command is a mandatory component of your WebView tracking implementation. This command: - **Initializes the tracking session** when the page loads in the WebView - **Enables data collection** by signaling to Contentsquare that tracking should begin - **Must be called from the tag code** regardless of whether you use GTM or manual injection - **Works in conjunction with the mobile SDK** to ensure proper data synchronization The command typically follows this format: ```javascript window._uxa.push([ "trackPageview", window.location.pathname + window.location.hash.replace("#", "?__"), ]); ``` This call should be included in every implementation method described below. (see [Track Pageviews](/en/webview-tracking-tag/track-pageviews/#trackpageview-command-differences)) ### Google Tag Manager (Template) You may already have implemented our GTM Tag (`Contentsquare - Main Tag`) for your website. Follow these steps to implement or verify the WebView setup. 1. Open your container and go to the **templates** section. ![](~/assets/web/gtm-template/main-1.png) 1. Select **Search gallery**. ![](~/assets/web/gtm-template/main-2.png) 1. Type in **`contentsquare`** and select the **Contentsquare - Main tag** option. ![](~/assets/web/gtm-template/main-3.png) 1. Click **Add to workspace**. ![](~/assets/web/gtm-template/main-4.png) 1. Confirm your choice by selecting **Add** ![](~/assets/web/gtm-template/main-5.png) 1. Go to the Tags section and click the **New** button to create a new tag. ![](~/assets/web/gtm-template/add-tag.png) 1. Configure it by selecting the top-right button. ![](~/assets/web/gtm-template/tag-config.png) 1. Search for **`contentsquare`** and select the **Contentsquare - Main tag** template that you've previously added to your container. ![](~/assets/web/gtm-template/new-main.png) 1. Confirm that your `my_web_tag_id` is correctly added. This should have been provided by your Contentsquare contact during your web implementation. 1. Similarly, confirm that your **my_webview_tag_id** is properly configured. This is also provided by your Contentsquare contact. ![](~/assets/webview/gtm_cs-contentsquare-tag_9_steps.jpg) 1. Select the **DOM Ready** as trigger. ![](~/assets/webview/gtm_cs-contentsquare-tag_11_steps.jpg) ### Google Tag Manager (Custom HTML) If your page loads in both a web and WebView environment, you should use a variable to determine whether the page is running in a WebView context before integrating the tracking tag. The Contentsquare Android and iOS SDK injects a `window.CS_isWebView` variable into the WebView to simplify the integration. 1. Add a new tag on your workspace. ![](~/assets/webview/gtm_cs-contentsquare-custom_tag_1_steps.png) 1. Select “Choose a tag type to begin setup…”. ![](~/assets/webview/gtm_cs-contentsquare-custom_tag_2_steps.png) 1. In the list, pick the “Custom HTML” tag. ![](~/assets/webview/gtm_cs-contentsquare-custom_tag_3_steps.png) 1. Copy and paste the following code in the Tag Configuration HTML section: ```html ``` ![](~/assets/webview/gtm_cs-contentsquare-custom_tag_4_steps.png) 1. Select “Choose a trigger to make this tag fire…” and pick "All Pages" from the list. ![](~/assets/webview/gtm_cs-contentsquare-custom_tag_trigger_steps.png) :::warning `window.CS_isWebView` is available since Contentsquare's iOS SDK 4.36.0, Android SDK 4.32.0, React Native Bridge 3.9.0 or Flutter Plugin 4.13.0. If you have a custom way of checking if the page is loaded in a WebView, replace `window.CS_isWebView` with your solution. ::: ### Manual injection To set up the tracking tag on your website, add the following lines of code on every page you want to analyze, either at the end of the `` tag. ```html ``` This code creates a function which will add an asynchronous call to a script and then execute the function. This is a way to avoid other elements loading being blocked on the page. This reduces the impact of the tag on your website’s performance. ## Validate WebView tracking To verify WebView tracking, refer to the documentation available for [iOS](/en/ios/track-webviews/#validate-webview-tracking) and [Android](/en/android/track-webviews/#validating-the-implementation-on-the-web-side). --- # Session Replay URL: https://docs.contentsquare.com/en/webview-tracking-tag/session-replay/ ## Session Replay WebView tracking prerequisites In order to have WebViews in the replays, Session Replay tracking needs to be set up on the native side. See [iOS](/en/ios/session-replay/#webview) and [Android](/en/android/session-replay/#webview) docs for prerequisites. ## How Session Replay WebView tracking works Similar to analytics events, once set in WebView mode, the Tag will collect Session Replay data and pass it to the native SDK, which will then send it to the dedicated Apps project. ## Personal Data Handling WebView personal data masking is entirely handled on the web side. Follow the web documentation section to implement personal data handling: [Personal Data Handling](/en/web/personal-data-handling/). ### About (remote) Session Replay data collection options [Session Replay data collection options](/en/web/personal-data-handling/#session-replay-data-collection-options) are also applied in WebView mode: - [Clear content with masked Personal Data](/en/web/personal-data-handling/#with-automasking-off) VS [Auto-masked content with AAA masking](/en/web/personal-data-handling/#with-automasking-on) - [Selectively mask pages by URL](/en/web/personal-data-handling/#selectively-mask-pages-by-url) --- # Track Pageviews URL: https://docs.contentsquare.com/en/webview-tracking-tag/track-pageviews/ To aggregate user behavior and engagement at the screen/page level, track page transitions by calling the [`trackPageview`](/en/web/command-reference/#trackpageview) command. ```javascript window._uxa = window._uxa || []; window._uxa.push(["trackPageview", "PAGE_TITLE_OR_URL"]); ``` The Tag logs a pageview event that identifies the new page with the page title that you provide. ## Track pageviews differences (with vs without WebView mode) Tracking Pageviews has different rules depending if the Tag is loaded in WebView mode or not. ### `trackPageview` command differences | Webview mode | Web context | | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | The Tag will not generate any natural pageview, you have to manually track all your screens. | The Tag will generate a natural pageview when loaded. | | The value you set is the one that will be seen in the Contentsquare platform. | The tag will prepend the value with the domain and append it with the query parameters. | | If no value (second array element) is provided, no default value will be provided | The tag will set the path as default value | ### Note on pageview tracking in WebView mode When set in WebView mode, the CS Tag will not trigger [natural pageviews](/en/web/sending-pageviews/#natural-pageview). If you rely on natural pageviews when the page is loaded from a web browser, make sure to use `trackPageview` as the page is fully loaded, as soon as possible. To do so, use the following code to call the `trackPageview` API as the DOM is ready: ```javascript document.addEventListener("DOMContentLoaded", function () { window._uxa = window._uxa || []; window._uxa.push(["trackPageview", "PAGE_TITLE_OR_URL"]); }); ``` --- # Track dynamic variables URL: https://docs.contentsquare.com/en/webview-tracking-tag/track-dynamic-variables/ ## General principles ### Usage Dynamic variables are additional information on the session that can be used to segment sessions. For example, they can include information on the A/B Test variations displayed to the current user. ### Limits #### On the server side - It is possible to save up to 40 distinct dynamic variable keys per screenview. If more are received, only the first 40 keys will be kept. - If you are using the same key twice on the same screenview, the last value associated with the key will be collected. #### On the SDK side - Every dynamic variable is composed of a pair of key (max. 50 characters) and value (max. 255 characters string or number of type `Long` between 0 and 232 - 1). In case these maximum lengths are reached, the SDK will automatically trim the exceeding characters. - If key or value are empty, the SDK will instead send the literal string "cs-empty". ## Defining dynamic variables To define and send a dynamic variable, directly use the key and String/Long value **once a first screenview has been triggered**: ```javascript window._uxa = window._uxa || []; window._uxa.push(["trackDynamicVariable", { key: my_key, value: my_value }]); // key is a string // value is either a string or an integer ``` **Type of the value** — The value can be either a **whole number** or a **string**. For each case, available features won't be the same in the Contentsquare app: - For **whole numbers**, you will be able to do some algebra. Example: _sessions with dynamic variable key = "numberOfFriends" and value >= 10_ - For **strings**, auto-completion and Regular Expression will be available. Example: _sessions with dynamic variable key = "accountType" and value = "Premium"_ --- # Track transactions URL: https://docs.contentsquare.com/en/webview-tracking-tag/track-transactions/ To associate a user's session with their potential purchases (and corresponding revenue), you must send the transaction via a dedicated API. For each transaction, we send: - Transaction ID - Revenue - Currency ```javascript window._uxa = window._uxa || []; window._uxa.push([ "ec:transaction:create", { id: "123" /* Transaction ID (string, up to 40 characters) */, revenue: "9.99" /* Transaction's total cost (integer or string, up to 12 digits and 2 decimals - extra decimals are truncated) */, currency: "usd" /* Currency value (string less than 10 characters or numeric/alphanumeric ISO 4217 value) */, }, ]); window._uxa.push(["ec:transaction:send"]); ``` :::warning **Each transaction must only be sent once**. A common mistake is to trigger the sending when the confirmation screen is displayed. This leads to triggering the transaction each time the user puts the app in background and then in foreground on the confirmation screen. ::: ## Currency The currency is conforming to the [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217#List_of_ISO_4217_currency_codes) standard. The currency must be passed as an "alphanumeric code". If the currency doesn't match the supported currencies, the SDK sends a currency value of `-1`. It will be processed as the default currency of the project. --- # Artificial Pageviews URL: https://docs.contentsquare.com/en/web/artificial-pageviews/ Artificial pageviews are to be used when: - An action completely changes the content displayed on the page without refreshing it and changing its URL (Ajax requests); - The site is built with a Single Page Application (SPA) and any related frameworks (React, Angular); - The user gets redirected to another step of a funnel without refreshing the page; - The site re-routes all the URL changes without refreshing the page; - The site is built as a Progressive Web App (PWA); - \*Important Modal/Popup windows are displayed.

Stable URLs - Modal windows and artificial pageviews tracking

For tracking **modal windows or events that don't change the URL structure**, you'll need to use the Contentsquare **Trackpageview** functionality by following these methods and binding them to the correct action (button click/event trigger).

Dynamic URLs - Single Page Applications and History Change

In the event of the **URL structure being changed** on each view change, we can keep track of this by **firing the Main Tag again**: the tag will automatically detect that it was previously put in place on the site and fire a new pageview instead. ## Google Tag Manager (Template) ### Stable URLs 1. Open your container and go to the **templates** section ![](~/assets/web/gtm-template/main-1.png) 1. Select **Search gallery** ![](~/assets/web/gtm-template/main-2.png) 1. Type in **`contentsquare`** and select the **Contentsquare - Artificial Pageview** option ![](~/assets/web/gtm-template/apv-1.png) 1. Click **Add to workspace** ![](~/assets/web/gtm-template/apv-2.png) 1. Confirm your choice by selecting **Add** ![](~/assets/web/gtm-template/main-5.png) 1. Go to the Tags section and click the **New** button to create a new tag ![](~/assets/web/gtm-template/add-tag.png) 1. Configure it by selecting the top-right button ![](~/assets/web/gtm-template/tag-config.png) 1. Type in **`contentsquare`** and select the **Contentsquare - Artificial Pageview** option ![](~/assets/web/gtm-template/apv-3.png) 1. Select the tag and configure: - Select the Free text option and enter the value under `Artificial Pageview value`. - If there's a pop-up on your website and you need to deploy APV, then select `This is for the opening a popup.` in the drop-down. :::note The value will be prefixed with `cs-popin-`. For instance `cs-popin-cart`, `cs-popin-wishlist`. ::: ![](~/assets/web/gtm-template/apv-4.png) ### Dynamic URLs 1. Amend the Main tag configuration by **adding a new trigger** to it. ![](~/assets/web/event/new_trigger.png) 1. Create a new trigger ![](~/assets/web/event/add_trigger.png) 1. Select **"Choose a trigger type to begin setup..."**. ![](~/assets/web/event/choose_trigger.png) 1. In the list, select the **"History Change"** trigger. ![](~/assets/web/event/history_change.png) 1. **Save** your trigger. ![](~/assets/web/event/save_history_change.png) 1. Select the **"Save"** button on the top right. ![](~/assets/web/event/save_final_triggers.png) ## Google Tag Manager (Custom HTML) ### Stable URLs 1. Select **"Choose a tag type to begin setup..."**. ![](~/assets/web/gtm/gtm-main-2.png) 1. In the list, pick the **"Custom HTML"** tag. ![](~/assets/web/gtm/gtm-main-3.png) 1. Write the snippet to be fired in the **HTML field**. It should be similar to this: ```html ``` ![](~/assets/web/gtm/gtm-main-4.png) 1. Select **"Choose a trigger to make this tag fire..."**. ![](~/assets/web/gtm/gtm-main-5.png) 1. Create a new trigger to make this tag fire ![](~/assets/web/event/add_trigger.png) 1. Select **"Choose a trigger type to begin setup..."**. ![](~/assets/web/event/choose_trigger.png) 1. In the list, pick the **"All Elements"** trigger. ![](~/assets/web/event/click_all_element.png) 1. Check **"Some Clicks"** ![](~/assets/web/event/some_click.png) 1. Select **"Click Element"**, **"matches CSS selector"** and enter a **valid CSS** filter corresponding to the element you want to track. For example the valid CSS for: ```html ``` Will be: ```css .btn.btn.primary ``` ![](~/assets/web/event/trigger_conditions.png) ### Dynamic URLs 1. Amend the Main tag configuration by **adding a new trigger** to it. ![](~/assets/web/event/new_trigger.png) 1. Create a new trigger ![](~/assets/web/event/add_trigger.png) 1. Select **"Choose a trigger type to begin setup..."**. ![](~/assets/web/event/choose_trigger.png) 1. In the list, select the **"History Change"** trigger. ![](~/assets/web/event/history_change.png) 1. **Save** your trigger. ![](~/assets/web/event/save_history_change.png) 1. Select the **"Save"** button on the top right. ![](~/assets/web/event/save_final_triggers.png) ## Tealium ### Stable URLs **Assign the event** you might already have in place a custom HTML snippet and write the snippet to be fired in the HTML field. It should be similar to this: ```html ``` ### Dynamic URLs Create (or select an already existing) event that occurs on each history change or view re-routing. Assign this event to the Contentsquare extension. ## Adobe Launch ### Stable URLs #### Artificial Pageviews When setting up the rule, **make sure to target the specific event or condition** needed. For instance, for an add to bag action, you could either follow the click route: ![](~/assets/web/launch/18-1.png) Or the custom event route: ![](~/assets/web/launch/18.png) Once you've chosen the desired event, you can select the Artificial Pageview tracking action from the Contentsquare extension. ![](~/assets/web/launch/19.png) Depending on the pageview you'd need to track, you can **either specify the query** to be passed to the Contentsquare servers **or leave the input field empty**, which will allow our script to capture the current URL automatically. ![](~/assets/web/launch/20.png) ![](~/assets/web/launch/20-1.png) You can also use **Data Elements** ![](~/assets/web/launch/20-2.png) ### Dynamic URLs In the event of a SPA implementation, if the path/query automatically changes on each re-routing, utilise the built-in history change event to fire the CS tag on each of these occurrences. ![](~/assets/web/launch/5-2.png) ## Commanders Act 1. To add a new event, go to the "EDIT" step, and click "ADD EVENT" (1): ![](~/assets/web/tagco/add_event.png) A configuration window will appear, with several fields: - (1) "Name": Name of the event you wish to add - (2) "Id": The event’s ID (to be completed only if you know it and want to trigger the event based on its ID; otherwise, leave the field empty, and it will be generated automatically by Commanders Act) - (3) JavaScript code: Area where the event’s JavaScript code is entered - (4) "Use Tag Cleaner": Feature allowing you to "correct" the event (rewrites it in order to avoid JavaScript errors and makes it compatible with the container’s code) ![](~/assets/web/tagco/add_event_detail.png) 1. Click "ADD" to add your event to the container. 1. Go to the tag library. Once there: 1. Write "Event Injection" in the search engine 1. Select the tag 1. Add the tag ![](~/assets/web/tagco/event_injection.png) In case of tracking pageviews with Contentsquare, the code to be deployed should follow this guideline: ```javascript window._uxa = window._uxa || []; window._uxa.push(['trackPageview', ]); ``` (4) Go to your website; place the cursor on the element you wish to place an event on and do a right click. In the menu that opens up, select "Inspect Element". (5) In the console, once the element is highlighted, right-click again. (6) Choose "copy" from the menu. (7) > "Copy Selector". :::note These actions on the site’s CSS are applicable to the Google Chrome browser only. ::: ![](~/assets/web/tagco/find_selector.png) (8) If you know the element’s ID (starting with a #, copy and paste it in the #CSS_PATH# field). ![](~/assets/web/tagco/css_path.png) (9) If you do not know or cannot find the ID, copy and paste the element’s information starting with "#" and replace " > "(space>space) with a single space in the code line. ![](~/assets/web/tagco/css_path2.png) (10) Copy and paste the line in the interface’s #CSS_Path# field. ![](~/assets/web/tagco/css_path3.png) Now enter the ID of the event you wish to summon in the corresponding field. Proceed to the deployment step as you do with other tags. ## Shopify 1. Within the main menu, select **Online Store > Themes**, then click the **Actions** drop-down menu, and **Edit Code**. ![](~/assets/web/shopify-interface-edit-code.png) 1. Open the relevant Liquid file where you want to trigger an artificial pageview based on your own JavaScript logic. You can put this in the main `theme.liquid` file or in a specific Liquid file. Let’s say you want to trigger this artificial pageview only when a certain action takes place like when an item is added to the cart. You would need to wrap this code inside your own condition, callback function, or event listener. 1. In the snippet below, replace `` with your unique path. ```html ``` You either hard-code a static value for the path like `Added_to_cart` or use Shopify’s [Liquid Objects](https://shopify.dev/api/liquid/objects)/[Liquid Tags](https://shopify.dev/api/liquid/tags) to grab the dynamic data from it like below: :::tip Check out Shopify's [Liquid Object cheat sheet](https://www.shopify.com/partners/shopify-cheat-sheet) ::: ```html ``` 1. Insert this code after the main tracking tag block. The end result of adding this code into the Liquid file: ```html ``` 1. To modify the entire path that is sent, use the `setPath` command: ```html ``` :::note You don’t need to supply a second parameter in the `trackPageview` command when it is set in the `setPath` command above it. ::: For more information, see the [`setPath` command](/en/web/sending-pageviews/#modifying-the-path). 1. To modify only the query string, use the `setQuery` command: ```html ``` :::note You don’t need to supply a second parameter in the `trackPageview` command when it is set in the `setQuery` command above it. ::: For more information, read about the [`setQuery` command](/en/web/sending-pageviews/#modifying-the-query-parameters). ## Custom HTML To send a pageview, use the `trackPageview` command: ```html ``` `` is limited to 255 characters. :::warning[Just the path] The Tag prepends the domain and appends the query parameters. Do not include the domain or the `#` character since everything which comes after is erased. ::: ### Stable URLs For instance, in case you wanted to keep track of the popup window appearing when adding an item to the cart: ```html ``` ### Dynamic URLs #### With custom variables ```html ``` #### Without custom variables ```html ``` ### Tracking a popin opening To track a popin opening/closure during the user's navigation, use **artificial pageviews**. 1. A first artificial pageview needs to be sent when the popin is opened — the sent URL will be the current one, followed by a string of characters allowing you to identify the popin. ```html ``` 1. A second artificial pageview needs to be sent when the popin is closed. The sent URL will be the current one. ```html ``` ### Single Page Application The Contentsquare Tracking tag sends only one pageview per full reload. In a Single Page Application (SPA), that would be only once per session. To handle this, **an [artificial pageview](/en/web/artificial-pageviews/#custom-html) on every page change** is needed — use the "History Change" event which is available in most Tag Management Systems. You can fire the following script on every page and on history change. It fires the main tag the first time and then sends an artificial pageview for each next call. ```html /YOUR_TAG_ID/ ``` ### Following a single page check-out If your checkout only fires one full reload, the main tag will be called just once, and only one natural pageview will be sent. We thus only collect: - `shop.com/checkout/` Instead of: - `shop.com/checkout/step1` - `shop.com/checkout/step2` - `shop.com/checkout/step3` - `shop.com/checkout/step4` To achieve this result, it is necessary to: 1. Change the natural pageview URL (the first that was sent) 1. Send an artificial pageview for every step Here is the corresponding code, which uses the [`setPath` function](/en/web/sending-pageviews/#modifying-the-path) and [artificial pageviews](/en/web/artificial-pageviews/#custom-html): ```javascript /* 1. Change the natural URL pageview, before loading the main tag */ window._uxa = window._uxa || []; window._uxa.push(["setPath", "checkout/step1"]); (function () { var mt = document.createElement("script"); mt.type = "text/javascript"; mt.async = true; mt.src = "//t.contentsquare.net/uxa/YOUR_TAG_ID.js"; document.getElementsByTagName("head")[0].appendChild(mt); })(); /* ... Step Change Event ... */ /* 2. Send an artificial page for every step change*/ window._uxa = window._uxa || []; window._uxa.push(["trackPageview", "checkout/step" + n]); /* Repeat step 2 as much as required */ ``` --- # Changelog URL: https://docs.contentsquare.com/en/web/changelog/ import { EmailForm } from "~/components";
Which version of the Tag is deployed on my website? Check your Tag version with the Contentsquare Tracking Setup Assistant Chrome extension: ![](~/assets/web/ctsa-find-tag-version.png)
## 15.125.0 - August 28st, 2025 **Features** - **Experience Analytics:** Refine checks for enabling new usage based quota. **Bug Fixes** - **Session Replay:** Ignore nested data-urls inside css rules. ## 15.125.0 - August 21st, 2025 **Features** - **Experience Analytics:** Enhance verify installation feature. - **Analytics:** Add murmur3 hashed target for heatmap. - **Voice of Customer:** Add metric to track legacy features. **Bug Fixes** - **Voice of Customer:** Ensure exclusivity between the unified and legacy VoC modules. - **Onboarding:** Enable verify installation feature in multiple scenarios. ## 15.121.0 - August 14th, 2025 **Features** - **WebView:** Add support for hierarchy identify and addUserProperties. - **Experience Analytics:** Add shared context in analytics requests. - **Experience Analytics:** Create verify installation CSQ-Lite Free/Growth. - **Voice of Customer:** Enable VoC module in no tracking mode. - **Voice of Customer:** Enable required globals in the unified VoC module. ## 15.114.0 - July 31st, 2025 **Features** - **Visual Labeler:** Add EU pipeline support. - **Experience Analytics:** Decommission legacy quota service. **Bug Fixes** - **Logging:** Improve logs context collection. ## 15.111.0 - July 24th, 2025 **Features** - **Identify**: Add EU pipeline support. ## 15.109.0 - July 17th, 2025 **Features** - **Session Replay**: Support disabled stylesheet property changes. **Bug Fixes** - **Session Replay**: Handle timing edge cases for `InputEvent`. - **Analytics:** Escape cookie value delimiter when stringifying. - **Session Replay**: When collection is paused because of user inactivity, still allow API and JS errors to be sent. ## 15.107.2 - July 10th, 2025 **Features** - **Session Replay**: Add flag to mask media elements when page is matching text replacement rules. - **Session Replay**: Support disabled stylesheet property changes. **Bug Fixes** - **Commands**: Ensure queued commands execute only after external component starts ## 15.105.5 - July 3rd, 2025 **Bug Fixes** - **Session Replay**: Ensure added nodes reference the proper parent context to avoid being auto-masked. - **Session Replay**: Clear page events callbacks when tracking stops to avoid duplicate events. ## 15.105.1 - June 26th, 2025 **Bug Fixes** - **WebView, Session Replay:** Fix CSS Link URL serialization. ## 15.105.0 - June 19th, 2025 **Features** - **Analytics:** Implement Product Analytics visual labeler for crosswriting customers. **Bug Fixes** - **Tag Configurator:** Fix `elementBecomesVisible` trigger schema. - **Session Replay:** Add support for Google Fonts stylesheets that don't use the `.css` extension. ## 15.104.2 - June 12th, 2025 **Features** - **Metrics:** Add new metrics for name and phone auto-masking. - **Analytics:** Implement option to collect `TargetText` on every click/tap/submit event. - **Session Replay:** Implement CSS styling rule change observer. - **Product Analytics:** Integrate product analytics view id in pageviews. **Bug Fixes** - **Session Replay:** Improve the debouncing and throttling mechanisms. - **Voice of Customer:** Ensure VoC URLs are synchronized with pageview URLs. - **Voice of Customer:** Remove ETR for surveys. - **Experience Monitoring:** Better handling for `TimeoutError` in Experience Monitoring. - **WebView:** Update masking state after artificial pageviews. - **Logger:** Ensure the logger preserves the caller's `this` context. ## 15.99.2 - May 28th, 2025 **Features** - **Experience Monitoring:** Mask name in API and custom error URLs. **Bug Fixes** - **Experience Monitoring:** Do not raise an error on signal timeout. - **Voice of Customers:** Synchronize URL with artificial pageview. - **Integration:** `onRecordingContextChange` command returns cleanup function. ## 15.94.1 - May 22th, 2025 **Features** - **Session Replay:** Reduce initial text visibility throttling for faster detection of visible text. - **Session Replay:** Introduce an experimental field to opt out of using the protected (unpatched) `MutationObserver` retrieved via iframe. ## 15.92.1 - May 15th, 2025 **Features** - **Metrics:** Normalize tracking of command misuse. - **Metrics:** Track CSP web worker security errors. - **Session Replay:** Mask elements with `contenteditable` attribute. - **Experience Monitoring:** Mask more name variants in custom errors. **Bug Fixes** - **Voice of Customer:** Fix incorrect URL passed to the VoC widget. ## 15.85.1 - April 30th, 2025 **Features** - **Metrics:** wrap all tag command usage and track misuse. - **Tag Configurator:** add help center links for each CSTC templates. - **Tag Configurator:** add best practice section for 'Network requests - Mask URLs' template. **Bug Fixes** - **WebView:** add protection against bad override of FileReader browser API ## 15.84.1 - April 15th, 2025 **Bug Fixes** - **Experience Analytics:** Solve the conflict with third-party `ping` events. - **Session Replay:** Support blank iframes. - **Metrics:** Change name of Tag Configurator metrics. - **Voice of Customer:** Send survey responses as internal events. - **Voice of Customer:** Set [survey cookie](/en/web/cookies/#_hjdonepolls) duration to 365 days. - **Voice of Customer:** Use milliseconds for survey cookie duration. ## 15.82.2 - April 8th, 2025 **Bug Fixes** - **Session Replay:** Support DST dates in replay targeting rules for Free and Growth plans. - **Metrics:** Avoid starting metrics in webview contexts due to missing APIs. **Features** - **Metrics:** Track usage of Tag Configurator triggers and templates. ## 15.81.3 - April 1st, 2025 **Bug fixes** - **Product Analytics:** Do not send the domain in `heap.setPath`. - **Experience Analytics:** Handle quota response when session expires. - **Voice of Customer:** Don't include VoC code in the tag if the VoC flag is disabled. **Features** - **Voice of Customer:** Introduce VoC only tracking. - **Metrics:** Implement command, encryption and masking metrics. - **Metrics:** Toggle metrics collection system on. ## 15.76.0 - March 20th, 2025 **Bug fixes** - **Tag Configurator:** Fix `BeforePageview` trigger. **Features** - **Product Analytics:** Send Product Analytics context in pageviews. - **Product Analytics:** Hierarchy collection for click, change, and submit events. - **Metrics:** Introduce a metrics collection system. ## 15.72.6 - March 13th, 2025 **Bug fixes** - **Webviews:** SerializeWebview `withAssets` not depending on staticResourceUrlTracker anymore. - **Session Replay:** Update serializer to ignore children already serialized and include mutation of `movedNode` into new one. - **Session Replay:** Change a query parameter for targeting rules collection mode. - **Product Analytics:** Use masked URL instead of path in `heap.setPath`. - **Product Analytics:** Create new command `sendHeapContext` for `heap.js` v5. - **Voice of Customer:** Initialize VoC on artificial page views. - **Experience Analytics:** Improve typing for Dynamic and Custom Variables modules. **Features** - **Product Analytics:** Start data collection for `heap.js` v4. - **Tag Configurator:** Cleanup obsolete template/triggers properties. ## 15.70.8 - February 26th, 2025 **Bug fixes** - **Experience Analytics:** Add a validity check on descriptor parameter of FilterUntrustedEvent. - **Tag Configurator:** Change template BlockAllowListForSR name. - **Session Replay:** Add source to masked Personal Data logs. - **Session Replay:** Avoid monkey patching the same API multiple times. - **Session Replay:** Partial matching patterns support placeholder matching empty URL token (bis). - **Static Resource Manager:** Update online assets collection on pageview. - **Session Replay:** Handle added text nodes. **Features** - **Tag Configurator:** Cleanup obsolete template/triggers properties. - **Webviews:** Send Tag configuration to parent. - **Product Analytics:** Implement `identify` and `addUserProperties` commands from `heap.js`. - **Session Replay:** Check if URL arguments are empty. ## 15.67.2 - February 20th, 2025 **Bug fixes** - **Session Replay:** Disabling session capture in CSQ Free and Growth plans does not stop data collection for Session Replay ## 15.66.2 - February 13th, 2025 **Bug fixes** - **Emerchandising:** Flush element source upon stop. - **Experience Analytics:** Do not stop tag performance tracker on artificial pageviews. - **Session Replay:** Fix mutation optimizer issue when removing nodes. **Features** - **Experience Analytics:** Pass disableTextCapture to trackPageview on artificial pageviews. - **Product Analytics:** Collect pageview from History changes and listen submit event. ## 15.65.0 - February 10th, 2025 **Bug fixes** - **API Errors:** Check the attribute value is not null or undefined. - **Session Replay:** Avoid collision with user defined selectors. - **Session Replay:** Check fetch request response on being undefined. - **Session Replay:** Move initialization of shadow root filter. **Features** - **Experience Analytics:** Do not start the tag when page is being pre-rendering (Chrome speculation API). - **Tag Configurator:** Support closest matching element in click trigger. - **Tag Configurator:** Support new condition operators. - **Tag Configurator:** Support tap in all snippets implementing the click trigger. - **Product Analytics:** Implement new command to send cross-product context. - **Session Replay:** Optimize number of mutation observers needed to track text visibility changes. ## 15.56.1 - January 30th, 2025 **Bug fixes** - **Session Replay:** Fix an issue on legacy masked rules from window after `startdatacollection` command. - **Session Replay:** Fix send initial input values on activity resume after the new initial DOM. - **Session Replay:** Fix on Static Resources Manager ensures online assets collection flag in iframes and nested iframes is correctly handled. - **Session Replay:** Fix ensures input events are sent after mutation on the element. - **Tag Configurator:** Fix filter untrusted events (events not triggered by visitor). **Features** - **Session Replay:** Manage added nodes to encrypted element. - **Session Replay:** Unify all Personal Data config modes. - **Tag Configurator:** New trigger on element becomes visible. ## 15.49.1 - January 9th, 2025 **Minor fixes** - **Session Replay:** Handle errors related to closed readable streams in the NetworkWorker. - **Session Replay:** Handle errors when `document.body` is not accessible in a cross-domain iframe. **Bug fixes** - **Session Replay:** Prevent data collection when the `optout` command is pushed before the Tag is injected or starts. - **Analytics:** Handle null values passed to the `trackError` command gracefully. **Features** - **Tag Configurator:** Restart implementation snippets on artificial page views and session renewal. - **Tag Configurator:** New implementation template for excluding & allowing URLs in Session Replay. - **Tag Configurator:** New implementation log level for logging warnings about broken implementations. - **Session Replay:** Add logs to track usage of Google's speculative rules API. - **Session Replay:** Unify the default element masking rules across all deployment modes. - **Session Replay:** Add validators and log warnings for the `setCapturedElementsSelector` command. ## 15.43.0 - December 18th, 2024 **Bug fixes** - **Session Replay:** Fix an issue which could cause text visibility events to be lost in some cases. - **Session Replay:** Fix an issue occurring when the zoom tracker was stopped before being started. - **Session Replay:** Fix the mutation serialization optimiser that was producing incorrect outputs in some edge cases. - **Session Replay:** Stop serializing script children. - **Session Replay:** Improve text visibility detection for inline elements. - **Integration:** Improve replay link format. - **Experience Monitoring:** Fix an issue where the `responseBody` was not collected in some cases. - **Experience Monitoring:** Fix an issue that caused an error to be thrown when getting the file name for JavaScript errors collection. **Features** - **Session Replay:** Update the validation of the format of the visitor cookie. - **Session Replay:** Mask by default text area content from appended text nodes in iframe context. ## 15.39.6 - December 12th, 2024 **Bug fixes** - **Session Replay:** Fixed the issue with Tag Download time parameter. - **Session Replay:** Restart VoC widgets on artificial page views. - **Session Replay:** Fixed video events race condition. - **Session Replay:** Mask emails only in `href` and `src` attributes. - **Session Replay (webview):** Set sensitive status at start. - **Experience Monitoring:** Catch abort when reading the response body. **Features** - **Session Replay:** Mask `href` and `src` attributes in specific nodes. - **Session Replay:** Optionally mask non-text elements using masking settings. - **Session Replay:** Remove phones from custom errors. ## 15.36.2 - November 20th, 2024 **Bug fixes** - **Session Replay:** Improve support of images by accepting alternate source elements. - **Session Replay:** Fix regression after a performance optimization linked to mutation processing. - **Experience Monitoring:** Limit JavaScript file names to 150 characters max. - **Experience Monitoring:** Replace script data URL by pageview URL. - **Experience Analytics:** Fix JS error thrown by `getCurrentOrientation` function during resize events. **Features** - **Personal Data:** Mask first and last names in error collection. ## 15.33.7 - November 13th, 2024 **Bug fixes** - **Session Replay:** Improve support of `data-cs-mask` with shadow DOM of masked elements. - **Session Replay:** Improve support of CSS inline rules during initial DOM serialization. - **Session Replay:** Avoid masking digits of node attributes when masking feature is enabled. - **Session Replay:** Preserve inputs radio name attribute when masking feature is enabled. - **Session Replay:** Fix `nextSibling` calculation to return `null` under certain conditions. - **Session Replay:** Mask `document.baseURI` attribute on initial DOM. **Performance Improvements** - Improved performance of element visibility trigger. **Features** - **Experience Analytics (Free and Growth)**: Integrate Targeting rules into data collection flow. - **Session Replay:** Capture nested elements added through DOM mutations with `data-cs-capture` and `setCapturedElementsSelector`. ## 15.28.0 - October 30th, 2024 **Bug fixes** - **Text Visibility:** Do not collect `