CustomerGlu Developer Documentation
  • 🔧Getting started
  • 🔧Quickstart Guide for React Web Apps
  • 📱Quickstart Guide for React Native Apps
  • 📱Quickstart Guide for Flutter Apps
  • Integrating with SDKs
    • Web SDK
    • Mobile SDKs
      • How to Test Integration?
    • Cordova SDK
    • Shopify
  • Integrating with APIs
    • Register User/Device
    • Load Campaigns
    • Binding Webview to Native App Functions
    • 🔍Using __GLU_NUDGE_CLICK for Widget Visibility
    • 🎯API-based Segmentation Quickstart Guide
  • 🔌Third-Party Integrations
    • Source
      • Sending Events directly from Server
      • Segment
      • Moengage
      • Amplitude
      • Clevertap
      • Webengage
    • Destination
      • Analytics Webhook
      • Customer.io
      • Talon.One
      • Segment
      • MoEngage
      • Amplitude
      • Clevertap
      • WebEngage
      • Google Sheets
    • Cohort
      • Mixpanel
  • Miscellaneous Topics
    • Direct Campaign/Wallet URLs
    • Configuring Webhooks
      • Rewards Webhook
      • Nudge Webhook
    • Notifications
      • FCM
      • APNs
      • CustomerGlu Notification
      • Testing Nudges
    • Referral Campaigns
      • Firebase
      • Branch
    • Handling Non Logged-in Users
    • Testing Campaigns with User Logs
    • Using the Editor
      • How to edit Buttons in Campaigns
    • How to Create and Manage Segments in CustomerGlu
  • SCHEMA REPOSITORY
    • Webhook Schema
      • Reward Webhook Schema
      • Nudge Webhook Schema
      • Raw Event Webhook Schema
    • Webview Callback Schema
      • Analytics Event Schema
    • Analytics schema V4
      • Page Events
      • Track Events (UI)
      • Track Events (SDK)
      • State-Change Events
      • System Events
    • 🗝️FAQ
      • API Key
      • How to find and add Screen Names for Entrypoints
  • Demo Apps
    • Demo Apps
Powered by GitBook
On this page
  • Overview
  • Data Structure
  • How to Access Widget Visibility?
  • Use Cases
  • Best Practices
  • Troubleshooting
  • Visibility Configuration

Was this helpful?

  1. Integrating with APIs

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 user

  • entrypointId: The ID representing the entry point where the widget is displayed

  • campaignId: The ID of the campaign associated with the widget

  • clickedCount: 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:

  1. Verify you're using the correct IDs (userId, entrypointId, campaignId)

  2. Check the raw localStorage data:

    javascriptCopyconsole.log(JSON.parse(localStorage.getItem("__GLU_NUDGE_CLICK")));
  3. Check if the visibility conditions have been customized in the CustomerGlu dashboard

  4. Verify there are no network issues preventing backend sync

Missing Data

If no data appears in localStorage:

  1. Confirm the user has interacted with at least one widget

  2. Check browser localStorage permissions and quotas

  3. 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:

  1. Navigate to the Campaign in CustomerGlu dashboard

  2. Select the Widget Configuration view

  3. Find and update the Visibility Conditions according to your needs

PreviousBinding Webview to Native App FunctionsNextAPI-based Segmentation Quickstart Guide

Last updated 2 months ago

Was this helpful?

🔍