🔍Using __GLU_NUDGE_CLICK for Widget Visibility
This guide explains how to programmatically check and respond to the visibility state of CustomerGlu widgets by accessing the __GLU_NUDGE_CLICK property stored in localStorage.
Overview
When a CustomerGlu widget reaches its completed
state, it stores interaction data in localStorage under the key __GLU_NUDGE_CLICK
. By default, the widget is automatically hidden when the click count is 1 or more.
Important Notes:
This data is also stored on the backend and synced across devices
The visibility threshold can be customized through Visibility Conditions under Widget Configuration view for a campaign
Data Structure
The __GLU_NUDGE_CLICK
property uses the following structure:
{
"userID": {
"entrypointId": {
"campaignId": {
"clickedCount": 1
}
}
}
}
Example Data
{
"glutest-c840f891-623a-4c0e-9024-3c429575a574": {
"66f6d8a92c87ddc90dac0fb5": {
"2512c8d6-1233-411f-8939-83ea68e50006": {
"clickedCount": 1
}
}
}
}
Field Explanation
userID
: A unique identifier for the userentrypointId
: The ID representing the entry point where the widget is displayedcampaignId
: The ID of the campaign associated with the widgetclickedCount
: The number of times the widget was clicked (widget is hidden when this equals or exceeds the configured threshold, default is 1)
How to Access Widget Visibility?
Basic Code Example
// Read and parse the localStorage data
function getWidgetData() {
const keyName = "__GLU_NUDGE_CLICK";
const storedData = localStorage.getItem(keyName);
if (storedData) {
try {
return JSON.parse(storedData);
} catch (error) {
console.error("Error parsing widget data:", error);
return null;
}
}
return null;
}
// Check if a specific widget should be visible
function isWidgetVisible(userId, entrypointId, campaignId) {
const data = getWidgetData();
if (!data) {
// No data means the widget hasn't been clicked yet
return true;
}
// Navigate through the nested structure to get clickCount
// Using optional chaining for safety
const clickCount = data[userId]?.[entrypointId]?.[campaignId]?.clickedCount || 0;
// Widget is hidden when clickCount is 1 or more (default configuration)
// Note: This threshold may be different if configured in the CustomerGlu dashboard
return clickCount < 1;
}
Use Cases
1. Conditional UI Rendering
function updateUI() {
const userId = "user-123"; // Your actual user ID
const entrypointId = "entry-456"; // Your entrypoint ID
const campaignId = "campaign-789"; // Your campaign ID
if (isWidgetVisible(userId, entrypointId, campaignId)) {
// Show related UI elements
document.getElementById("related-element").style.display = "block";
} else {
// Hide related UI elements or show alternatives
document.getElementById("related-element").style.display = "none";
document.getElementById("alternative-element").style.display = "block";
}
}
2. Listening for Visibility Changes
function setupVisibilityListener(userId, entrypointId, campaignId, callback) {
// Initial check
callback(isWidgetVisible(userId, entrypointId, campaignId));
// Listen for localStorage changes
window.addEventListener("storage", (event) => {
if (event.key === "__GLU_NUDGE_CLICK") {
callback(isWidgetVisible(userId, entrypointId, campaignId));
}
});
}
// Usage
setupVisibilityListener("user-123", "entry-456", "campaign-789", (isVisible) => {
console.log("Widget is now:", isVisible ? "visible" : "hidden");
updateUI();
});
3. Integration with Segment API
This example shows how to combine widget visibility with the Segmentation API:
async function handleWidgetCompletion(userId, campaignId) {
// Check if widget is hidden (completed)
const isVisible = isWidgetVisible(userId, entrypointId, campaignId);
if (!isVisible) {
// Widget is completed, move user to next campaign
try {
// Remove from current campaign
await fetch(`https://api-us.customerglu.com/segment/${campaignId}/user/delete`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': 'your-api-key'
},
body: JSON.stringify({ userId })
});
// Add to next campaign
await fetch(`https://api-us.customerglu.com/segment/next-campaign-id/user/add`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': 'your-api-key'
},
body: JSON.stringify({ userId })
});
} catch (error) {
console.error("Error updating user segments:", error);
}
}
}
Best Practices
1. Defensive Coding
Always implement error handling when accessing localStorage:
javascriptCopyfunction getClickCount(userId, entrypointId, campaignId) {
try {
const data = getWidgetData();
return data?.[userId]?.[entrypointId]?.[campaignId]?.clickedCount || 0;
} catch (error) {
console.error("Error getting click count:", error);
return 0; // Default on error
}
}
2. Performance Considerations
Avoid checking localStorage in tight loops or high-frequency events
Consider caching the result if checking frequently:
javascriptCopy// Cache visibility state with a simple refresh mechanism
const visibilityCache = {
data: {},
timestamp: 0,
ttl: 5000, // 5 seconds cache validity
getVisibility(userId, entrypointId, campaignId) {
const key = `${userId}:${entrypointId}:${campaignId}`;
const now = Date.now();
// Refresh cache if expired
if (now - this.timestamp > this.ttl) {
this.data = {};
this.timestamp = now;
}
// Return cached value if exists
if (this.data[key] !== undefined) {
return this.data[key];
}
// Calculate and cache new value
const isVisible = isWidgetVisible(userId, entrypointId, campaignId);
this.data[key] = isVisible;
return isVisible;
}
};
3. Cross-Device Considerations
Since the widget state is synced across devices via the backend, users will generally see consistent widget visibility across their devices. However, there might be a short delay in synchronization.
Troubleshooting
Widget Visibility Inconsistencies
If the widget visibility state seems inconsistent:
Verify you're using the correct IDs (userId, entrypointId, campaignId)
Check the raw localStorage data:
javascriptCopyconsole.log(JSON.parse(localStorage.getItem("__GLU_NUDGE_CLICK")));
Check if the visibility conditions have been customized in the CustomerGlu dashboard
Verify there are no network issues preventing backend sync
Missing Data
If no data appears in localStorage:
Confirm the user has interacted with at least one widget
Check browser localStorage permissions and quotas
Verify the CustomerGlu SDK is properly initialized
Visibility Configuration
The default behavior is to hide widgets when clickCount is 1 or more, but this can be customized:
Navigate to the Campaign in CustomerGlu dashboard
Select the Widget Configuration view
Find and update the Visibility Conditions according to your needs
Last updated
Was this helpful?