How to set up Cookieless Tracking in GA4
You can set up cookieless tracking in GA4 (Google Analytics 4) by using the following storage mechanism (instead of cookies) to achieve as much functionality as possible without compromising user experience, functionality, or data privacy.
- Data Layers.
- Session Storage.
- Local Storage.
- URL Parameters.
- Server-side storage.
- Server-side tracking.
If you prefer a video tutorial:
#1 Use a data layer instead of a first-party cookie for storing real-time data.
If you want to temporarily store data (like the data from UTM parameters) before consent is granted, use the data layer instead of the first-party cookie.
That way, you don’t need to place any analytics cookie before the consent is granted.
When a user lands on your page, you can capture the UTM parameters from the URL and temporarily store them in the data layer.
// Initialize the data layer if it doesn't already exist
window.dataLayer = window.dataLayer || [];
// Function to get URL parameters (UTM values in this case)
function getURLParameter(name) {
let regex = new RegExp('[?&]' + name + '=([^&#]*)', 'i');
let result = regex.exec(window.location.href);
return result ? decodeURIComponent(result[1]) : null;
}
// Capture UTM parameters from the URL
let utmSource = getURLParameter('utm_source');
let utmMedium = getURLParameter('utm_medium');
let utmCampaign = getURLParameter('utm_campaign');
// Temporarily store UTM data in the data layer
window.dataLayer.push({
'event': 'UTMParametersCaptured',
'utm_source': utmSource,
'utm_medium': utmMedium,
'utm_campaign': utmCampaign
});
// Log the data layer for demonstration purposes
console.log(window.dataLayer);
Once the user consents to tracking (through a cookie consent banner), you can then move the data from the data layer to an analytics tool like GA4.
// Simulate user consent (In a real scenario, this would be triggered by a consent banner)
function userConsentGranted() {
// Find the UTM parameters event in the data layer
let utmData = window.dataLayer.find(event => event.event === 'UTMParametersCaptured');
if (utmData) {
// Send the UTM parameters to GA4 using gtag()
gtag('event', 'utm_capture', {
'utm_source': utmData.utm_source,
'utm_medium': utmData.utm_medium,
'utm_campaign': utmData.utm_campaign
});
console.log("UTM parameters sent to GA4:", utmData);
}
}
// Example: Call the consent function once consent is granted (e.g., after the user clicks "Accept")
userConsentGranted();
Note: Only pass necessary and lightweight data through the data layer. For larger datasets, rely on server-side storage. Server-side storage replaces cookies for handling large or sensitive datasets that can’t be handled efficiently in the data layer.
#2 Use Session Storage for storing session specific data.
Use ‘Session Storage’ for data that only needs to persist for the duration of a user’s session. The session ends when a browser tab or window is closed by a user.
Session Storage is a part of web storage API that provides a programmatic interface for developers to interact with the browser’s session storage mechanism.
SessionStorage can replace analytics cookies for session-specific analytics, tracking user behaviour, page views, and interactions during a single session.
This approach is privacy-friendly because data is automatically cleared once the session ends (i.e. when the user closes the browser tab or window).
For example,
You can track how many pages a user views during a session by using session storage:
// Initialize or retrieve the page view count from SessionStorage
let pageViews = parseInt(sessionStorage.getItem('pageViews')) || 0;
// Increment the page view count for each page visit
pageViews += 1;
// Store the updated page view count in SessionStorage
sessionStorage.setItem('pageViews', pageViews);
console.log(`Pages viewed this session: ${pageViews}`);
You can track how many times a user clicks a specific button during the session.
// Retrieve or initialize button click count from SessionStorage
let buttonClicks = parseInt(sessionStorage.getItem('buttonClicks')) || 0;
// Add an event listener to the button
document.getElementById('subscribeButton').addEventListener('click', function() {
// Increment the click count each time the button is clicked
buttonClicks += 1;
// Store the updated click count in SessionStorage
sessionStorage.setItem('buttonClicks', buttonClicks);
console.log(`Button clicked ${buttonClicks} times this session.`);
});
Tracking items added to a cart using SessionStorage
You can track items added to a shopping cart using SessionStorage by storing the cart data in an array or object, updating it as the user adds items, and retrieving it when needed during the session.
For example, each time a user adds an item to the cart, you update the cart stored in SessionStorage.
// Function to add an item to the cart
function addItemToCart(item) {
// Retrieve the current cart from SessionStorage, or initialize an empty array if it doesn't exist
let cart = JSON.parse(sessionStorage.getItem('shoppingCart')) || [];
// Check if the item already exists in the cart
let existingItem = cart.find(cartItem => cartItem.id === item.id);
if (existingItem) {
// If the item already exists, update the quantity
existingItem.quantity += item.quantity;
} else {
// If the item doesn't exist, add it to the cart
cart.push(item);
}
// Store the updated cart back in SessionStorage
sessionStorage.setItem('shoppingCart', JSON.stringify(cart));
console.log('Cart Updated:', cart);
}
// Example of adding an item to the cart
addItemToCart({ id: 1, name: 'Laptop', quantity: 1, price: 999.99 });
addItemToCart({ id: 2, name: 'Mouse', quantity: 2, price: 49.99 });
You can retrieve the cart from SessionStorage and display the items on the cart page.
// Function to display cart items
function displayCartItems() {
// Retrieve the shopping cart from SessionStorage
let cart = JSON.parse(sessionStorage.getItem('shoppingCart')) || [];
// If the cart is empty, display a message
if (cart.length === 0) {
console.log('Your cart is empty.');
return;
}
// Display each item in the cart
cart.forEach(item => {
console.log(`Item: ${item.name}, Quantity: ${item.quantity}, Price: $${item.price}`);
});
}
// Example of displaying the cart items
displayCartItems();
You can also remove an item from the cart and update SessionStorage.
// Function to remove an item from the cart
function removeItemFromCart(itemId) {
// Retrieve the cart from SessionStorage
let cart = JSON.parse(sessionStorage.getItem('shoppingCart')) || [];
// Filter out the item with the given ID
cart = cart.filter(item => item.id !== itemId);
// Update the cart in SessionStorage
sessionStorage.setItem('shoppingCart', JSON.stringify(cart));
console.log('Item removed. Updated Cart:', cart);
}
// Example of removing an item from the cart
removeItemFromCart(1); // Removes the item with ID 1
Note: Session Storage is not designed for long-term tracking. If you need to achieve long-term tracking without relying on cookies, consider alternative approaches, such as LocalStorage, server-side storage, or user authentication.
#3 Use Local Storage for storing persistent, non-sensitive data across sessions.
Use ‘Local Storage’ for storing persistent, non-sensitive data across multiple sessions.
Local Storage is a part of web storage API that provides a programmatic interface for developers to interact with the browser’s session storage mechanism.
LocalStorage can replace analytics persistent cookies for storing non-sensitive, persistent data that needs to remain across sessions and page reloads.
This approach is privacy-friendly because, unlike cookies, LocalStorage does not automatically transmit data to the server with each HTTP request, reducing the risk of unwanted data sharing or tracking across different websites.
For example,
You can use LocalStorage to store a unique identifier for each user.
This identifier helps in recognising returning users across multiple sessions:
// Check if the client ID already exists in LocalStorage
let clientId = localStorage.getItem('clientId');
if (!clientId) {
// Generate a new client ID and store it in LocalStorage
clientId = 'client_' + Date.now() + Math.random().toString(36).substring(2);
localStorage.setItem('clientId', clientId);
console.log('New client ID generated:', clientId);
} else {
console.log('Returning user with client ID:', clientId);
}
// Send the client ID to GA4
gtag('event', 'identify_user', {
'client_id': clientId
});
You can store user preferences (such as theme, language, or layout settings) in LocalStorage so that they persist across sessions.
// Store a user preference in LocalStorage
function setUserPreference(theme, language) {
localStorage.setItem('theme', theme);
localStorage.setItem('language', language);
console.log(`User preferences set: Theme = ${theme}, Language = ${language}`);
// Send the user preferences to GA4
gtag('event', 'set_user_preferences', {
'theme': theme,
'language': language
});
}
// Retrieve user preferences from LocalStorage
function getUserPreferences() {
const theme = localStorage.getItem('theme');
const language = localStorage.getItem('language');
console.log('Retrieved user preferences:', { theme, language });
return { theme, language };
}
// Example usage
setUserPreference('dark', 'en');
const preferences = getUserPreferences();
You can track the number of sessions a user has completed by incrementing a session counter in LocalStorage.
// Retrieve the session count from LocalStorage or initialize it
let sessionCount = parseInt(localStorage.getItem('sessionCount')) || 0;
// Increment the session count each time a new session starts
sessionCount += 1;
// Store the updated session count in LocalStorage
localStorage.setItem('sessionCount', sessionCount);
console.log(`User has completed ${sessionCount} sessions.`);
// Send the session count to GA4
gtag('event', 'session_count', {
'session_count': sessionCount
});
You can store and update the total number of purchases made by a user in LocalStorage.
// Retrieve the purchase count from LocalStorage or initialize it
let purchaseCount = parseInt(localStorage.getItem('purchaseCount')) || 0;
// Function to update purchase count
function recordPurchase() {
// Increment the purchase count when a purchase is made
purchaseCount += 1;
// Store the updated purchase count in LocalStorage
localStorage.setItem('purchaseCount', purchaseCount);
console.log(`User has made ${purchaseCount} purchases.`);
// Send the updated purchase count to GA4
gtag('event', 'purchase_made', {
'purchase_count': purchaseCount
});
}
// Example usage: Call recordPurchase() when a purchase is completed
recordPurchase();
#4 Use URL Parameters for cross-page tracking.
You can use URL parameters to pass tracking data from one page to another without relying on cookies or local storage.
This method is particularly useful when tracking data needs to be persisted across multiple pages but in a privacy-friendly way.
URL parameters are visible in the browser’s address bar and can be easily shared, logged, or cached.
If sensitive information (like personally identifiable information) is included in URL parameters, it may be exposed to third parties or leaked unintentionally.
Avoid storing sensitive data in URL parameters. If you have to store sensitive data, use anonymised or hashed values.
Use URL parameters in combination with sessionStorage or localStorage to avoid having to pass the data across every page via URLs.
For example, if you capture the UTM parameters on the landing page, store them in sessionStorage, and use them throughout the session without exposing them in subsequent URLs.
URL parameters offer a privacy-friendly alternative to cookies for passing session data between pages.
Unlike cookies, which are stored on the user’s device, URL parameters are transmitted with each page request. This means that sensitive data is not stored locally.
#5 Use server-side storage for sensitive or long-term tracking.
Server-side storage is a more secure and privacy-friendly approach for handling sensitive or long-term tracking compared to client-side mechanisms like cookies, LocalStorage, or SessionStorage.
Server-side storage refers to data stored on a web server or in a database that the server manages.
This data typically relates to user sessions, application state, or preferences.
Server-side storage data is more secure and reliable because it’s not affected by browser settings or user actions (like clearing cookies or switching devices).
Note: Cookies and server storage often work together. But server-side storage can function without cookies.
Key differences between DataLayers, SessionStorage, LocalStorage and ServerStorage
Following are the key differences between DataLayers, SessionStorage, LocalStorage, and ServerStorage in terms of their scope, persistence, and functionality:
Feature Data Layers SessionStorage LocalStorage Server-Side Storage
Location Temporary storage in the data layer (client-side). Stored in the user’s browser (client-side). Stored in the user’s browser (client-side). Stored on the server (server-side).
Persistence Exists for as long as the page/session exists; cleared after use. Data is cleared when the browser tab or window is closed. Data persists indefinitely until manually cleared. Data persists as long as needed, based on server configuration.
Scope Available during the page lifecycle, shared across scripts and tags. Specific to a single tab or window (session-specific). Not shared between tabs or windows. Shared across all tabs and windows for the same origin. Accessible from any client-side request (via API, session, etc.), independent of the user’s browser or device.
Data Access Can be accessed by scripts and tags running on the page. Only available while the browser tab is open. Available across all sessions until explicitly cleared. Accessed through HTTP requests (such as REST APIs) or via a session identifier sent from the client.
Size Limit No fixed size, but used for small data sets. Typically around 5MB per origin. Typically around 5MB per origin. No fixed size limit, determined by server storage capacity.
Visibility Not visible to the user; only accessible by scripts running on the page. Data is visible only to client-side scripts running on the same page. Data is visible to client-side scripts running on the same origin. Not visible to the client unless requested explicitly via HTTP.
Security Susceptible to client-side vulnerabilities like XSS but limited scope. Vulnerable to client-side attacks like XSS (Cross-Site Scripting). Vulnerable to client-side attacks like XSS. More secure as it is stored on the server, but requires secure access mechanisms (e.g., SSL, authentication).
Data Lifespan Temporary; lasts only during the session or page lifecycle. Exists only for the current session (until the tab is closed). Persists until manually cleared by the user or programmatically removed. Can persist for any duration, based on server policies or database configuration.
Use Cases Triggering real-time events, temporary tracking for analytics or marketing. Temporary data (e.g., session-specific user interactions, form data). Persistent data (e.g., user preferences, theme settings, login tokens). Long-term data storage (e.g., user profiles, transaction data, session management).
Data Sharing Data can be shared across scripts and tags on the same page. Data is not shared between tabs, even if they are from the same domain. Data is shared across all tabs and windows for the same domain. Data can be shared across devices and sessions, based on user authentication or session tokens.
Availability Across Devices Not accessible across devices or sessions; only valid during page view. Not accessible across devices or browsers. Not accessible across devices or browsers. Accessible from any device, as long as the user has the appropriate credentials or session information.
Data Management Managed by the website or tag management system. Managed by the browser. Can be cleared when the tab or window is closed. Managed by the browser. Can be cleared manually by the user or programmatically. Managed by the server. Data management policies (backup, deletion) are controlled by the server or database.
For best results, use server-side storage along with data layers, sessionStorage, localStorage and URL parameters.
Each method complements the others by handling different types of data with various levels of security and persistence, ensuring both user privacy and website functionality.
Scenario: A user visits an e-commerce website, adds a product to their cart, and proceeds to checkout.
Landing Page:
- The user lands on the website with UTM parameters in the URL.
- The UTM parameters are captured and added to the data layer.
- The UTM parameters are stored in local storage for future reference.
Product Page:
- When a user views a product, the product information (e.g., productId, productName, productPrice) is added to the data layer.
- The viewed product is added to a session-based “recently viewed” list in session storage.
Cart Page:
- When a user adds a product to their cart, an ‘addToCart’ event is triggered, and the product information is added to the data layer.
- The user’s cart items are stored in local storage to persist across sessions.
- The cart data is sent to the server and stored in a database.
Checkout Page:
- Checkout events (e.g., ‘checkoutStarted’, ‘checkoutCompleted’) are triggered with relevant data.
- The checkout data is stored on the server, including customer information, shipping address, and payment details.
- Any temporary session data, such as shipping methods or coupon codes, is cleared.
By relying on data layers, SessionStorage, LocalStorage, URL parameters, and server-side storage, you can achieve the same functionality traditionally handled by first-party analytics cookies without compromising user experience, functionality, or data privacy.
#6 Server Side Tracking
GA4 Server Side Tracking is another cookiless tracking method in GA4.
Srver-side tracking allows you to send tracking data directly from your server to GA4, bypassing the need to rely on client-side cookies for user identification and behaviour tracking.
Server-side tracking allows you to overcome ad blockers, cookie consent issues and browser restrictions (such as ITP in Safari or ETP in Firefox), which can block or limit traditional cookie-based tracking.
Since data is processed server-side, you have more control over what data is collected, how it is anonymized, and when it is sent to GA4.
Following is an example of how you might send a page view event from your server to GA4 with the measurement protocol.
const axios = require('axios');
// Function to send a page view event to GA4
function trackPageView(userId, pageTitle, pageLocation) {
const data = {
client_id: userId, // User identifier (can be a custom ID generated server-side)
events: [
{
name: "page_view",
params: {
page_title: pageTitle,
page_location: pageLocation,
}
}
]
};
// Send data to GA4 Measurement Protocol
axios.post('https://www.google-analytics.com/mp/collect?measurement_id=YOUR_GA4_MEASUREMENT_ID&api_secret=YOUR_GA4_API_SECRET', data)
.then(response => {
console.log('Page view tracked', response.data);
})
.catch(error => {
console.error('Error tracking page view', error);
});
}
// Example usage: track a page view
trackPageView('user_12345', 'Home Page', 'https://example.com/home');
You can set up cookieless tracking in GA4 (Google Analytics 4) by using the following storage mechanism (instead of cookies) to achieve as much functionality as possible without compromising user experience, functionality, or data privacy.
- Data Layers.
- Session Storage.
- Local Storage.
- URL Parameters.
- Server-side storage.
- Server-side tracking.
If you prefer a video tutorial:
#1 Use a data layer instead of a first-party cookie for storing real-time data.
If you want to temporarily store data (like the data from UTM parameters) before consent is granted, use the data layer instead of the first-party cookie.
That way, you don’t need to place any analytics cookie before the consent is granted.
When a user lands on your page, you can capture the UTM parameters from the URL and temporarily store them in the data layer.
// Initialize the data layer if it doesn't already exist
window.dataLayer = window.dataLayer || [];
// Function to get URL parameters (UTM values in this case)
function getURLParameter(name) {
let regex = new RegExp('[?&]' + name + '=([^&#]*)', 'i');
let result = regex.exec(window.location.href);
return result ? decodeURIComponent(result[1]) : null;
}
// Capture UTM parameters from the URL
let utmSource = getURLParameter('utm_source');
let utmMedium = getURLParameter('utm_medium');
let utmCampaign = getURLParameter('utm_campaign');
// Temporarily store UTM data in the data layer
window.dataLayer.push({
'event': 'UTMParametersCaptured',
'utm_source': utmSource,
'utm_medium': utmMedium,
'utm_campaign': utmCampaign
});
// Log the data layer for demonstration purposes
console.log(window.dataLayer);
Once the user consents to tracking (through a cookie consent banner), you can then move the data from the data layer to an analytics tool like GA4.
// Simulate user consent (In a real scenario, this would be triggered by a consent banner)
function userConsentGranted() {
// Find the UTM parameters event in the data layer
let utmData = window.dataLayer.find(event => event.event === 'UTMParametersCaptured');
if (utmData) {
// Send the UTM parameters to GA4 using gtag()
gtag('event', 'utm_capture', {
'utm_source': utmData.utm_source,
'utm_medium': utmData.utm_medium,
'utm_campaign': utmData.utm_campaign
});
console.log("UTM parameters sent to GA4:", utmData);
}
}
// Example: Call the consent function once consent is granted (e.g., after the user clicks "Accept")
userConsentGranted();
Note: Only pass necessary and lightweight data through the data layer. For larger datasets, rely on server-side storage. Server-side storage replaces cookies for handling large or sensitive datasets that can’t be handled efficiently in the data layer.
#2 Use Session Storage for storing session specific data.
Use ‘Session Storage’ for data that only needs to persist for the duration of a user’s session. The session ends when a browser tab or window is closed by a user.
Session Storage is a part of web storage API that provides a programmatic interface for developers to interact with the browser’s session storage mechanism.
SessionStorage can replace analytics cookies for session-specific analytics, tracking user behaviour, page views, and interactions during a single session.
This approach is privacy-friendly because data is automatically cleared once the session ends (i.e. when the user closes the browser tab or window).
For example,
You can track how many pages a user views during a session by using session storage:
// Initialize or retrieve the page view count from SessionStorage
let pageViews = parseInt(sessionStorage.getItem('pageViews')) || 0;
// Increment the page view count for each page visit
pageViews += 1;
// Store the updated page view count in SessionStorage
sessionStorage.setItem('pageViews', pageViews);
console.log(`Pages viewed this session: ${pageViews}`);
You can track how many times a user clicks a specific button during the session.
// Retrieve or initialize button click count from SessionStorage
let buttonClicks = parseInt(sessionStorage.getItem('buttonClicks')) || 0;
// Add an event listener to the button
document.getElementById('subscribeButton').addEventListener('click', function() {
// Increment the click count each time the button is clicked
buttonClicks += 1;
// Store the updated click count in SessionStorage
sessionStorage.setItem('buttonClicks', buttonClicks);
console.log(`Button clicked ${buttonClicks} times this session.`);
});
Tracking items added to a cart using SessionStorage
You can track items added to a shopping cart using SessionStorage by storing the cart data in an array or object, updating it as the user adds items, and retrieving it when needed during the session.
For example, each time a user adds an item to the cart, you update the cart stored in SessionStorage.
// Function to add an item to the cart
function addItemToCart(item) {
// Retrieve the current cart from SessionStorage, or initialize an empty array if it doesn't exist
let cart = JSON.parse(sessionStorage.getItem('shoppingCart')) || [];
// Check if the item already exists in the cart
let existingItem = cart.find(cartItem => cartItem.id === item.id);
if (existingItem) {
// If the item already exists, update the quantity
existingItem.quantity += item.quantity;
} else {
// If the item doesn't exist, add it to the cart
cart.push(item);
}
// Store the updated cart back in SessionStorage
sessionStorage.setItem('shoppingCart', JSON.stringify(cart));
console.log('Cart Updated:', cart);
}
// Example of adding an item to the cart
addItemToCart({ id: 1, name: 'Laptop', quantity: 1, price: 999.99 });
addItemToCart({ id: 2, name: 'Mouse', quantity: 2, price: 49.99 });
You can retrieve the cart from SessionStorage and display the items on the cart page.
// Function to display cart items
function displayCartItems() {
// Retrieve the shopping cart from SessionStorage
let cart = JSON.parse(sessionStorage.getItem('shoppingCart')) || [];
// If the cart is empty, display a message
if (cart.length === 0) {
console.log('Your cart is empty.');
return;
}
// Display each item in the cart
cart.forEach(item => {
console.log(`Item: ${item.name}, Quantity: ${item.quantity}, Price: $${item.price}`);
});
}
// Example of displaying the cart items
displayCartItems();
You can also remove an item from the cart and update SessionStorage.
// Function to remove an item from the cart
function removeItemFromCart(itemId) {
// Retrieve the cart from SessionStorage
let cart = JSON.parse(sessionStorage.getItem('shoppingCart')) || [];
// Filter out the item with the given ID
cart = cart.filter(item => item.id !== itemId);
// Update the cart in SessionStorage
sessionStorage.setItem('shoppingCart', JSON.stringify(cart));
console.log('Item removed. Updated Cart:', cart);
}
// Example of removing an item from the cart
removeItemFromCart(1); // Removes the item with ID 1
Note: Session Storage is not designed for long-term tracking. If you need to achieve long-term tracking without relying on cookies, consider alternative approaches, such as LocalStorage, server-side storage, or user authentication.
#3 Use Local Storage for storing persistent, non-sensitive data across sessions.
Use ‘Local Storage’ for storing persistent, non-sensitive data across multiple sessions.
Local Storage is a part of web storage API that provides a programmatic interface for developers to interact with the browser’s session storage mechanism.
LocalStorage can replace analytics persistent cookies for storing non-sensitive, persistent data that needs to remain across sessions and page reloads.
This approach is privacy-friendly because, unlike cookies, LocalStorage does not automatically transmit data to the server with each HTTP request, reducing the risk of unwanted data sharing or tracking across different websites.
For example,
You can use LocalStorage to store a unique identifier for each user.
This identifier helps in recognising returning users across multiple sessions:
// Check if the client ID already exists in LocalStorage
let clientId = localStorage.getItem('clientId');
if (!clientId) {
// Generate a new client ID and store it in LocalStorage
clientId = 'client_' + Date.now() + Math.random().toString(36).substring(2);
localStorage.setItem('clientId', clientId);
console.log('New client ID generated:', clientId);
} else {
console.log('Returning user with client ID:', clientId);
}
// Send the client ID to GA4
gtag('event', 'identify_user', {
'client_id': clientId
});
You can store user preferences (such as theme, language, or layout settings) in LocalStorage so that they persist across sessions.
// Store a user preference in LocalStorage
function setUserPreference(theme, language) {
localStorage.setItem('theme', theme);
localStorage.setItem('language', language);
console.log(`User preferences set: Theme = ${theme}, Language = ${language}`);
// Send the user preferences to GA4
gtag('event', 'set_user_preferences', {
'theme': theme,
'language': language
});
}
// Retrieve user preferences from LocalStorage
function getUserPreferences() {
const theme = localStorage.getItem('theme');
const language = localStorage.getItem('language');
console.log('Retrieved user preferences:', { theme, language });
return { theme, language };
}
// Example usage
setUserPreference('dark', 'en');
const preferences = getUserPreferences();
You can track the number of sessions a user has completed by incrementing a session counter in LocalStorage.
// Retrieve the session count from LocalStorage or initialize it
let sessionCount = parseInt(localStorage.getItem('sessionCount')) || 0;
// Increment the session count each time a new session starts
sessionCount += 1;
// Store the updated session count in LocalStorage
localStorage.setItem('sessionCount', sessionCount);
console.log(`User has completed ${sessionCount} sessions.`);
// Send the session count to GA4
gtag('event', 'session_count', {
'session_count': sessionCount
});
You can store and update the total number of purchases made by a user in LocalStorage.
// Retrieve the purchase count from LocalStorage or initialize it
let purchaseCount = parseInt(localStorage.getItem('purchaseCount')) || 0;
// Function to update purchase count
function recordPurchase() {
// Increment the purchase count when a purchase is made
purchaseCount += 1;
// Store the updated purchase count in LocalStorage
localStorage.setItem('purchaseCount', purchaseCount);
console.log(`User has made ${purchaseCount} purchases.`);
// Send the updated purchase count to GA4
gtag('event', 'purchase_made', {
'purchase_count': purchaseCount
});
}
// Example usage: Call recordPurchase() when a purchase is completed
recordPurchase();
#4 Use URL Parameters for cross-page tracking.
You can use URL parameters to pass tracking data from one page to another without relying on cookies or local storage.
This method is particularly useful when tracking data needs to be persisted across multiple pages but in a privacy-friendly way.
URL parameters are visible in the browser’s address bar and can be easily shared, logged, or cached.
If sensitive information (like personally identifiable information) is included in URL parameters, it may be exposed to third parties or leaked unintentionally.
Avoid storing sensitive data in URL parameters. If you have to store sensitive data, use anonymised or hashed values.
Use URL parameters in combination with sessionStorage or localStorage to avoid having to pass the data across every page via URLs.
For example, if you capture the UTM parameters on the landing page, store them in sessionStorage, and use them throughout the session without exposing them in subsequent URLs.
URL parameters offer a privacy-friendly alternative to cookies for passing session data between pages.
Unlike cookies, which are stored on the user’s device, URL parameters are transmitted with each page request. This means that sensitive data is not stored locally.
#5 Use server-side storage for sensitive or long-term tracking.
Server-side storage is a more secure and privacy-friendly approach for handling sensitive or long-term tracking compared to client-side mechanisms like cookies, LocalStorage, or SessionStorage.
Server-side storage refers to data stored on a web server or in a database that the server manages.
This data typically relates to user sessions, application state, or preferences.
Server-side storage data is more secure and reliable because it’s not affected by browser settings or user actions (like clearing cookies or switching devices).
Note: Cookies and server storage often work together. But server-side storage can function without cookies.
Key differences between DataLayers, SessionStorage, LocalStorage and ServerStorage
Following are the key differences between DataLayers, SessionStorage, LocalStorage, and ServerStorage in terms of their scope, persistence, and functionality:
Feature | Data Layers | SessionStorage | LocalStorage | Server-Side Storage |
---|
Location | Temporary storage in the data layer (client-side). | Stored in the user’s browser (client-side). | Stored in the user’s browser (client-side). | Stored on the server (server-side). |
Persistence | Exists for as long as the page/session exists; cleared after use. | Data is cleared when the browser tab or window is closed. | Data persists indefinitely until manually cleared. | Data persists as long as needed, based on server configuration. |
Scope | Available during the page lifecycle, shared across scripts and tags. | Specific to a single tab or window (session-specific). Not shared between tabs or windows. | Shared across all tabs and windows for the same origin. | Accessible from any client-side request (via API, session, etc.), independent of the user’s browser or device. |
Data Access | Can be accessed by scripts and tags running on the page. | Only available while the browser tab is open. | Available across all sessions until explicitly cleared. | Accessed through HTTP requests (such as REST APIs) or via a session identifier sent from the client. |
Size Limit | No fixed size, but used for small data sets. | Typically around 5MB per origin. | Typically around 5MB per origin. | No fixed size limit, determined by server storage capacity. |
Visibility | Not visible to the user; only accessible by scripts running on the page. | Data is visible only to client-side scripts running on the same page. | Data is visible to client-side scripts running on the same origin. | Not visible to the client unless requested explicitly via HTTP. |
Security | Susceptible to client-side vulnerabilities like XSS but limited scope. | Vulnerable to client-side attacks like XSS (Cross-Site Scripting). | Vulnerable to client-side attacks like XSS. | More secure as it is stored on the server, but requires secure access mechanisms (e.g., SSL, authentication). |
Data Lifespan | Temporary; lasts only during the session or page lifecycle. | Exists only for the current session (until the tab is closed). | Persists until manually cleared by the user or programmatically removed. | Can persist for any duration, based on server policies or database configuration. |
Use Cases | Triggering real-time events, temporary tracking for analytics or marketing. | Temporary data (e.g., session-specific user interactions, form data). | Persistent data (e.g., user preferences, theme settings, login tokens). | Long-term data storage (e.g., user profiles, transaction data, session management). |
Data Sharing | Data can be shared across scripts and tags on the same page. | Data is not shared between tabs, even if they are from the same domain. | Data is shared across all tabs and windows for the same domain. | Data can be shared across devices and sessions, based on user authentication or session tokens. |
Availability Across Devices | Not accessible across devices or sessions; only valid during page view. | Not accessible across devices or browsers. | Not accessible across devices or browsers. | Accessible from any device, as long as the user has the appropriate credentials or session information. |
Data Management | Managed by the website or tag management system. | Managed by the browser. Can be cleared when the tab or window is closed. | Managed by the browser. Can be cleared manually by the user or programmatically. | Managed by the server. Data management policies (backup, deletion) are controlled by the server or database. |
For best results, use server-side storage along with data layers, sessionStorage, localStorage and URL parameters.
Each method complements the others by handling different types of data with various levels of security and persistence, ensuring both user privacy and website functionality.
Scenario: A user visits an e-commerce website, adds a product to their cart, and proceeds to checkout.
Landing Page:
- The user lands on the website with UTM parameters in the URL.
- The UTM parameters are captured and added to the data layer.
- The UTM parameters are stored in local storage for future reference.
Product Page:
- When a user views a product, the product information (e.g., productId, productName, productPrice) is added to the data layer.
- The viewed product is added to a session-based “recently viewed” list in session storage.
Cart Page:
- When a user adds a product to their cart, an ‘addToCart’ event is triggered, and the product information is added to the data layer.
- The user’s cart items are stored in local storage to persist across sessions.
- The cart data is sent to the server and stored in a database.
Checkout Page:
- Checkout events (e.g., ‘checkoutStarted’, ‘checkoutCompleted’) are triggered with relevant data.
- The checkout data is stored on the server, including customer information, shipping address, and payment details.
- Any temporary session data, such as shipping methods or coupon codes, is cleared.
By relying on data layers, SessionStorage, LocalStorage, URL parameters, and server-side storage, you can achieve the same functionality traditionally handled by first-party analytics cookies without compromising user experience, functionality, or data privacy.
#6 Server Side Tracking
GA4 Server Side Tracking is another cookiless tracking method in GA4.
Srver-side tracking allows you to send tracking data directly from your server to GA4, bypassing the need to rely on client-side cookies for user identification and behaviour tracking.
Server-side tracking allows you to overcome ad blockers, cookie consent issues and browser restrictions (such as ITP in Safari or ETP in Firefox), which can block or limit traditional cookie-based tracking.
Since data is processed server-side, you have more control over what data is collected, how it is anonymized, and when it is sent to GA4.
Following is an example of how you might send a page view event from your server to GA4 with the measurement protocol.
const axios = require('axios');
// Function to send a page view event to GA4
function trackPageView(userId, pageTitle, pageLocation) {
const data = {
client_id: userId, // User identifier (can be a custom ID generated server-side)
events: [
{
name: "page_view",
params: {
page_title: pageTitle,
page_location: pageLocation,
}
}
]
};
// Send data to GA4 Measurement Protocol
axios.post('https://www.google-analytics.com/mp/collect?measurement_id=YOUR_GA4_MEASUREMENT_ID&api_secret=YOUR_GA4_API_SECRET', data)
.then(response => {
console.log('Page view tracked', response.data);
})
.catch(error => {
console.error('Error tracking page view', error);
});
}
// Example usage: track a page view
trackPageView('user_12345', 'Home Page', 'https://example.com/home');
My best selling books on Digital Analytics and Conversion Optimization
Maths and Stats for Web Analytics and Conversion Optimization
This expert guide will teach you how to leverage the knowledge of maths and statistics in order to accurately interpret data and take actions, which can quickly improve the bottom-line of your online business.
Master the Essentials of Email Marketing Analytics
This book focuses solely on the ‘analytics’ that power your email marketing optimization program and will help you dramatically reduce your cost per acquisition and increase marketing ROI by tracking the performance of the various KPIs and metrics used for email marketing.
Attribution Modelling in Google Analytics and BeyondSECOND EDITION OUT NOW!
Attribution modelling is the process of determining the most effective marketing channels for investment. This book has been written to help you implement attribution modelling. It will teach you how to leverage the knowledge of attribution modelling in order to allocate marketing budget and understand buying behaviour.
Attribution Modelling in Google Ads and Facebook
This book has been written to help you implement attribution modelling in Google Ads (Google AdWords) and Facebook. It will teach you, how to leverage the knowledge of attribution modelling in order to understand the customer purchasing journey and determine the most effective marketing channels for investment.