Hello! I'm looking at getting a Pro license but I have some questions about API usage limits and som...
w

Wendi Fan

over 1 year ago
Hello! I'm looking at getting a Pro license but I have some questions about API usage limits and some miscellaneous questions I had from reading the documentation. Would someone be able to help me answer these? Thanks! 1. We’re looking to integrate several GrowthBook SDKs with our website – in particular, for C#, Javascript and React. There’s several separate React instances on our website at the moment, which as I understand it would need to separately call loadFeatures(). a. Would these all count as separate calls to the API, i.e. require 4+ per session? b. Would subsequent requests from the same user (as identified by provided attributes) be cached by your CDN, Fastly? c. If they do get cached, is there any guidance on how often it’s fetched from cache vs as a fresh request? 2. The React documentation describes two parameters, subscribeToChanges and backgroundSync. a. We’re planning to set backgroundSync to false, to disable streaming updates. What is the difference between this and subscribeToChanges? (Are they the same thing, where the name changed at some point?) 3. Visual Editor in React a. For use in React components, we need to call gb.setUrl() so active experiments can update. Does this count as an API request to GrowthBook? 4. The React documentation mentions Remote Evaluation, and that Cloud customers need to host a GrowthBook Proxy for this. a. Can you give an example of when I might want/need to use remote evaluation? How do I work out if this is something I need? 5. There is a onFeatureUsage parameter. I’d like to understand how this works with Percentage Rollout. In particular, the documentation states: "Percentage Rollouts do not fire any tracking calls so there's no way to precisely correlate the rollout to changes in your application's metrics." a. Does this mean that whilst we cannot track metrics in GrowthBook directly when performing percentage rollout, we can still track this ourselves e.g. by using onFeatureUsage to send a tracking event to our GA4 implementation? 6. Flickering a. As I understand it, it’s inevitable that there will be some extent of flicker for client side A/B testing. i. Is there any advantage to using the Visual Editor using the SDK over the GTM tag? ii. Would feature A/B tests be affected by flicker at all?
Hi team, We integrated GrowthBook SDK using GTM tag and used the snippet provided in documentation. ...
h

Harshul Kumar

over 1 year ago
Hi team, We integrated GrowthBook SDK using GTM tag and used the snippet provided in documentation. After integration we noticed a huge spike in organic search traffic in GA4(Screen Attached). We paused the Growthbook tag and spike got dissolved. Just to verify we enabled the same tag and noticed that spike is occurring again. Can anyone help and explain why is this happening in our case? I have also shared the GTM tag snippet below.
<script id="growthbook-sdk" src="<https://cdn.jsdelivr.net/npm/@growthbook/growthbook/dist/bundles/index.min.js>" defer></script>
<script>
	

(function() {

    window.getUUID = function() {
        var COOKIE_NAME = "gbuuid";
        var COOKIE_DAYS = 3 ; // 400 days is the max cookie duration for chrome

        // use the browsers crypto.randomUUID if set
        function generateUUID() {
            if (window.crypto != undefined && window.crypto.randomUUID != undefined && typeof window.crypto.randomUUID == 'function') {
                return window.crypto.randomUUID();
            } else {
                return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
                    var r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0,
                        v = c === 'x' ? r : (r & 0x3 | 0x8);
                    return v.toString(16);
                });
            }
        }

        function setCookie(name, value, days) {
    var expires;
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
        expires = '; expires=' + date.toGMTString();
    } else {
        expires = '';
    }
    var cookieName = '' + name + '';
    var cookieStr = cookieName + '=' + value + expires + ';' + 'domain=' + '.' + removeDomainPrefix(
        window.location.hostname
   ) + ';path=/';
    typeof window !== 'undefined' ?
        (document.cookie = cookieStr) :
        '';
}


        // get the existing UUID from cookie if set, otherwise create one and store it in the cookie
        if (window.readCookie(COOKIE_NAME)) return window.readCookie(COOKIE_NAME);

        var uuid = generateUUID();
        setCookie(COOKIE_NAME, uuid,COOKIE_DAYS);
        return uuid;
    }

    
    window.getCurrentEpochTime = function() {
        // Create a new Date object and use the getTime() method to get the current timestamp in milliseconds.
        var currentTimeMillis = new Date().getTime();

        // Convert the timestamp from milliseconds to seconds by dividing it by 1000.
        var currentEpochTime = Math.floor(currentTimeMillis / 1000);

        return currentEpochTime;
    }
    window.readCookie = function(cookieName) {
        var name = cookieName + "=";
        var decodedCookie = decodeURIComponent(document.cookie);
        var cookieArray = decodedCookie.split(';');

        for (var i = 0; i < cookieArray.length; i++) {
            var cookie = cookieArray[i];
            while (cookie.charAt(0) === ' ') {
                cookie = cookie.substring(1);
            }
            if (cookie.indexOf(name) === 0) {
                return cookie.substring(name.length, cookie.length);
            }
        }

        // Return false if the cookie is not found
        return false;
    }

    // Wait for the SDK to load before starting GrowthBook
    if (window.growthbook) {
        startGrowthbook();
    } else {
        document.querySelector("#growthbook-sdk").addEventListener("load", startGrowthbook);
    }

    function startGrowthbook() {

        if (!window.growthbook) return;
        console.log(window.growthbook, "window.growthbook")

        var exp = dataLayer[0].all_experiment_objects[0]


        window.gbuuid = window.getUUID();
        window.gb = new growthbook.GrowthBook({
            apiHost: "<https://cdn.growthbook.io>",
            clientKey: "sdk-YSiLEOQJVJKOggX",
            // TODO: Add decryptionKey if using encryption
            attributes: {
                id: window.gbuuid,
                expValue: dataLayer[0].optimize_all_experiment_experiment_id
                //add any other attributes here
            },
            debug: true,
            enableDebugMode: true,

            enableDevMode: true,
            subscribeToChanges: true,
            trackingCallback: function(experiment, result) {
                // track with GA4, for example:
 //               console.log("experiment-result", experiment, result)
                dataLayer.push({
                    event: 'experiment_viewed',
                    type: 'experiment',
                    experiment_id: experiment.key,
                    variation_id: result.variationId,
                    user_id: window.gbuuid,
                })


            }
        });
        window.gb.loadFeatures().then(function() {
            // if you want to do anything after GB loads
            // Object.keys(window.gb.getFeatures()).map(function(feature) {
            //     console.log(feature + " variation assigend feature call -> " + window.gb.getFeatureValue(feature, "fallback"))
 
                
            // })
          var exp = dataLayer[0].all_experiment_objects;
                if (exp && exp.length) {
                    exp.map(function(ele) {
                      var featureValue = window.gb.getFeatureValue(ele.google_exp_id.toLowerCase(), "fallback");
                       // console.log(ele.google_exp_id + " variation assigend exp call -> " + featureValue)
                       
                      if(featureValue !== "fallback" && featureValue !== -1){
                        dataLayer.push({
                            event: 'experiment_viewed',
                            type: 'experiment',
                            experiment_id: ele.name,
                            variation_id: featureValue,
                            user_id: window.gbuuid,
                        })
                      }

                    })

                }
        });
    }

})();

</script>