Docs > JavaScript SDK

JavaScript SDK



Copy link to clipboard

Download and Installation

Copy link to clipboard


  1. GameAnalytics.js include local logging to the console and is 65Kb in size.
  2. GameAnalytics.min.js is without logging and is 53Kb in size.

It is recommended to initially use GameAnalytics.js while implementing the needed tracking.

This will make it easier to verify correct SDK instrumentation. When done it is possible to switch to GameAnalytics.min.js in production if it is needed to save the extra kilobytes.

Unzip the downloaded .zip and include this in your project (the files are located in the dist folder):

<script src="/path/to/GameAnalytics.js" />


<script src="/path/to/GameAnalytics.min.js" />

NPM Install

If you use node packages you can also install the SDK via npm:

npm install gameanalytics

And use it like this:

var gameanalytics = require('gameanalytics');
gameanalytics .GameAnalytics.setEnabledInfoLog(true);

NOTE: The SDK still expects to be run in a browser environment where the navigator object is defined

The JavaScript GA Snippet

It is also possible to use the following snippet to asynchronously load GameAnalytics SDK when your website loads and still be able to configure, initialize and send events before the SDK is fully loaded (just like you can do with Google Analytics). The code should be added near the top of the tag and before any other script or CSS tags:

<!-- GameAnalytics -->
(function(w,d,a,m){var s='script';var g='GameAnalytics';w[g]=w[g]||function(){(w[g].q=w[g].q||[]).push(arguments)},a=d.createElement(s),m=d.getElementsByTagName(s)[0];a.async=1;a.src='[VERSION].min.js';m.parentNode.insertBefore(a,m)})(window,document);

GameAnalytics("setEnabledInfoLog", true);
GameAnalytics("initialize", "GAME_KEY", "SECRET_KEY");
<!-- End GameAnalytics -->

The above code does four main things:

  1. Creates a script element that starts asynchronously downloading the GameAnalytics.js JavaScript library from[VERSION].min.js (replace [VERSION] with the latest or desired version of the SDK)
  2. Initializes a global GameAnalytics function (called the GameAnalytics() command queue) that allows you to schedule commands to be run once the GameAnalytics.js library is loaded and ready to go.
  3. Adds a command to the GameAnalytics() command queue to enable info logging.
  4. Adds another command to the GameAnalytics() command queue to initialize the SDK (replace GAME_KEY and SECRET_KEY with your actual keys).

Alternative Async GA Snippet

While the JavaScript GA snippet described above ensures the script will be loaded and executed asynchronously on all browsers, it has the disadvantage of not allowing modern browsers to preload the script.

The alternative async GA snippet below adds support for preloading, which will provide a small performance boost on modern browsers, but can degrade to synchronous loading and execution on IE 9 and older mobile browsers that do not recognize the async script attribute. Only use this tracking snippet if your visitors primarily use modern browsers to access your site.

<!-- GameAnalytics -->
GameAnalytics("setEnabledInfoLog", true);
GameAnalytics("initialize", "GAME_KEY", "SECRET_KEY");
<script async src='[VERSION].min.js></script>
<!-- End GameAnalytics -->



Command Queue

Copy link to clipboard

The JavaScript GA snippet defines a global ga function known as the “command queue”.

It’s called the command queue because rather than executing the commands it receives immediately, it adds them to a queue that delays execution until the GameAnalytics.js library is fully loaded.

In JavaScript, functions are also objects, which means they can contain properties. The GA snippet defines a q property on the GameAnalytics function object as an empty array. Prior to the GameAnalytics.js library being loaded, calling the ga() function appends the list of arguments passed to the GameAnalytics() function to the end of the q array.

For example, if you were to run the GA snippet and then immediately log the contents of GameAnalytics.q to the console, you’d see an array, two items in length, containing the two sets of arguments already passed to the GameAnalytics() function:


// Outputs the following:
// [
//   ['setEnabledInfoLog', true],
//   ['initialize', 'GAME_KEY', 'SECRET_KEY']
// ]

Once the GameAnalytics.js library is loaded, it inspects the contents of the GameAnalytics.q array and executes each command in order. After that, the GameAnalytics() function is redefined, so all subsequent calls execute immediately.

This pattern allows developers to use the GameAnalytics() command queue without having to worry about whether or not the analytics.js library has finished loading. It provides a simple, synchronous-looking interface that abstracts away most of the complexities of asynchronous code.

Adding Commands To The Queue

All calls to the GameAnalytics() command queue share a common signature. The first parameter, the “command”, is a string that identifies a particular GameAnalytics.js method. Any additional parameters are the arguments that get passed to that method.

The rest of the documentation will refer to how to call methods unsing the traditional way and using the GameAnalytics() command queue.



Copy link to clipboard

You only need to read this page is your are interested in modifying and building the SDK from Typescript source. If you aren’t you can skip this section.


  • Node.js
  • Gulp

Run the following command to install all devDependencies:

npm install

All source code (Typescript) is located in src and resulting distribution files from building are placed in dist.

To build run:


This will build GameAnalytics.d.ts (declaration file), GameAnalytics.debug.js (includes sourcemap, not uglified), GameAnalytics.js (logging included, uglified, around 65Kb in size) and GameAnalytics.min.js (no logging included, uglified, around 53Kb in size).

Alternatively you can just build one of the targets by running one of these commands:

gulp normal
gulp debug
gulp mini
gulp declaration

No Logging Included

If you want to build the mini-release without logging included to save on the build size you can add the –nologging argument:

gulp mini --nologging


To run the test, run:

gulp test

initialize sdk

Copy link to clipboard

Using the SDK

Copy link to clipboard

Now we should be ready for adding code to activate the SDK! There are 3 phases the SDK will go through.

  1. Configuration
  2. Initialization
  3. Adding events or changing dimensions

The configuration and initialization steps should be called when the application starts.

Configuration calls configure settings for the SDK and some will not be able to be altered after initialize has been called.

Initialize call will start the SDK and activate the first session.

Once step 1 & 2 is done you can add events at different parts of the game code where some relevant action is happening.

Remember to add this line to the html file whenever you need to call the SDK.

<script src="/path/to/GameAnalytics.js">// <![CDATA[


<script src="/path/to/GameAnalytics.min.js" /> -->




Copy link to clipboard

The available configuration options are listed here.

  • build
  • custom userId
  • available (allowed) custom dimensions
  • available (allowed) resource currencies
  • available (allowed) resource item types


Build is used to specify the current version of your game. Specify it using a string. Recommended to use a 3 digit version like [major].[minor].[patch]

<!-- Traditional way -->
gameanalytics.GameAnalytics.configureBuild("android 1.0.0");
<!-- Command queue -->
GameAnalytics("configureBuild", "android 1.0.0");<a id="custom-userid"></a>

Custom UserID

The SDK will automatically generate a user id and this is perfectly fine for almost all cases.
Sometimes it is useful to supply this user_id manually – for example if you download raw data for processing and need to match your internal user id (could be a database index on your user table) to the data collected through GameAnalytics. Do not use a custom userId unless you have a specific need for using it.
Note that if you introduce this into a game that is already deployed (using the automatic id) it will start counting existing users as new users and your metrics will be affected. Use this from the start of the app lifetime when you need.


GameAnalytics("configureUserId", "user1234567879");

Specifying Allowed Values

For certain types it is required to define a whitelist containing possible unique values during the configuration phase. When the SDK is being used (after initialization) only the specified values will be allowed. 20 values are allowed for each list.

Processing many unique dimension values can be taxing for our servers. A few games with a poor implementation can seriously increase our cost and affect stability. Games will be blocked if they submit too many unique dimension values. We have this configuration requirement to guide users into planning what dimension values can be used.

gameanalytics.GameAnalytics.configureAvailableResourceCurrencies(["gems", "gold"]);
gameanalytics.GameAnalytics.configureAvailableResourceItemTypes(["boost", "lives"]);
gameanalytics.GameAnalytics.configureAvailableCustomDimensions01(["ninja", "samurai"]);
gameanalytics.GameAnalytics.configureAvailableCustomDimensions02(["whale", "dolphin"]);
gameanalytics.GameAnalytics.configureAvailableCustomDimensions03(["horde", "alliance"]);

GameAnalytics("configureAvailableResourceCurrencies", ["gems", "gold"]);
GameAnalytics("configureAvailableResourceItemTypes", ["boost", "lives"]);
GameAnalytics("configureAvailableCustomDimensions01", ["ninja", "samurai"]);
GameAnalytics("configureAvailableCustomDimensions02", ["whale", "dolphin"]);
GameAnalytics("configureAvailableCustomDimensions03", ["horde", "alliance"]);

Each resource currency string should only contain [A-Za-z] characters

Enable/disable event submission

If you for GDPR purposes need to disable event submission you can call the following:


GameAnalytics("setEnabledEventSubmission", false);

By default event submission is of course enabled. You will still receive configs if you have set any for your game even after disabling event submission.



Copy link to clipboard

Call this method to initialize using the game key and secret key for your game:

<!-- Traditional way -->
gameanalytics.GameAnalytics.initialize("[game key]", "[secret key]");
<!-- Command queue -->
GameAnalytics("initialize", "[game key]", "[secret key]");


Don’t have any keys yet? Head over here and register your game at the GameAnalytics website!

You can then find your game’s keys within the game settings.

Below is a common example of the code placed in a script lets call it main.js.

function onStart(){
    // ... other code from your project ...



    gameanalytics.GameAnalytics.configureAvailableResourceCurrencies(["gems", "gold"]);
    gameanalytics.GameAnalytics.configureAvailableResourceItemTypes(["boost", "gold"]);
    gameanalytics.GameAnalytics.configureAvailableCustomDimensions01(["ninja", "samurai"]);
    gameanalytics.GameAnalytics.configureAvailableCustomDimensions02(["whale", "dolphin"]);
    gameanalytics.GameAnalytics.configureAvailableCustomDimensions03(["horde", "alliance"]);

    gameanalytics.GameAnalytics.initialize([game key]", "[secret key]);

    GameAnalytics("setEnabledInfoLog", true);
    GameAnalytics("setEnabledVerboseLog", true);

    GameAnalytics("configureBuild", "0.10");

    GameAnalytics("configureAvailableResourceCurrencies", ["gems", "gold"]);
    GameAnalytics("configureAvailableResourceItemTypes", ["boost", "gold"]);
    GameAnalytics("configureAvailableCustomDimensions01", ["ninja", "samurai"]);
    GameAnalytics("configureAvailableCustomDimensions02", ["whale", "dolphin"]);
    GameAnalytics("configureAvailableCustomDimensions03", ["horde", "alliance"]);

    GameAnalytics("initialize", [game key]", "[secret key]);

adding events

Copy link to clipboard

GameAnalytics supports 5 different types of events

Event Description
Business Track player In-App Purchases.
Resource Managing the flow of virtual currencies – like gems or lives.
Progression Level attempts with Start, Fail & Complete event.
Error Submit exception stack traces or custom error messages.
Design Submit custom event id’s. Useful for tracking metrics specifically needed for your game.

Event Types

Read our in-depth guide to understand what and how to track events



Copy link to clipboard

Business events are used to track real-money transactions.

Field Type Description Example
currency string Currency code in ISO 4217 format.
amount integer Amount in cents. 99 is 0.99$
itemType string The type / category of the item. GoldPacks
itemId string Specific item bought. 1000GoldPack
cartType string The game location of the purchase.
Max 10 unique values.

When a purchase is completed, there are 2 ways to track the event:

<!-- Traditional way -->
gameanalytics.GameAnalytics.addBusinessEvent("[currency]", [amount], "[itemType]", "[itemId]", "[cartType]");
<!-- Command queue -->
GameAnalytics("addBusinessEvent", "[currency]", [amount], "[itemType]", "[itemId]", "[cartType]");


Copy link to clipboard

Resource events are used to register the flow of your in-game economy (virtual currencies) – the sink (subtract) and the source (add) for each virtual currency.

Before calling the resource event it is needed to specify what discrete values can be used for currencies and item types in the Configuration phase.

source (add)

Add gem currency from an in-app purchase.

gameanalytics.GameAnalytics.addResourceEvent(gameanalytics.EGAResourceFlowType.Source, "Gems", 400, "IAP", "Coins400");

GameAnalytics("addResourceEvent", "Source", "Gems", 400, "IAP", "Coins400");

sink (subtract)

Subtract a gem currency to buy an item.

gameanalytics.GameAnalytics.addResourceEvent(gameanalytics.EGAResourceFlowType.Sink, "Gems", 400, "IAP", "Coins400");

GameAnalytics("addResourceEvent", "Sink", "Gems", 400, "IAP", "Coins400");

Subtract a gem currency to source (buy) some amount of another virtual currency (BeamBooster).

gameanalytics.GameAnalytics.addResourceEvent(ga.EGAResourceFlowType.Sink, "Gems", 100, "Boosters", "BeamBooster5Pack");

gameanalytics.GameAnalytics.addResourceEvent(ga.EGAResourceFlowType.Source, "BeamBooster", 5, "Gems", "BeamBooster5Pack");

GameAnalytics("addResourceEvent", "Sink", "Gems", 100, "Boosters", "BeamBooster5Pack");

GameAnalytics("addResourceEvent", "Source", "BeamBooster", 5, "Gems", "BeamBooster5Pack");

Subtract 3 BeamBooster currency that were used during a level.

gameanalytics.GameAnalytics.addResourceEvent(ga.EGAResourceFlowType.Sink, "BeamBooster", 3, "Gameplay", "BeamBooster5Pack");
<!-- Command queue -->
GameAnalytics("addResourceEvent", "Sink", "BeamBooster", 3, "Gameplay", "BeamBooster5Pack");
Field Type Description Example
flowType enum A defined enum for sourcing and sinking resources. gameanalytics.EGAResourceFlowType.Sink
currency string The resource type/currency to track. Has to be one of the configured available resource currencies.
This string can only contain [A-Za-z] characters.
Gems, BeamBoosters, Coins
amount float Amount sourced or sinked. 0 or negative numbers are not allowed. 100.0
itemType string For sink events it can describe an item category you are buying (Weapons) or a place (Gameplay) the currency was consumed. For source events it can describe how the currency was gained. For example “IAP” (for in-app purchase) or from using another currency (Gems). Has to be one of the configured available itemTypes. Weapons, IAP, Gameplay, Boosters
itemId string For sink events it can describe the specific item (SwordOfFire) gained. If consumed during Gameplay you can simply use “Consumed”. For source events it describes how the player got the added currency. This could be buying a pack (BoosterPack5) or earned through Gameplay when completing a level (LevelEnd). BoosterPack5, SwordOfFire, LevelEnd, Coins400

Be careful to not call the resource event too often!
In a game where the user collect coins fairly fast you should not call a Source event on each pickup. Instead you should count the coins and send a single Source event when the user either complete or fail the level.



Copy link to clipboard

To add a progression event call the following function:

gameanalytics.GameAnalytics.addProgressionEvent(gameanalytics.EGAProgressionStatus.Start, "world01", "stage01", "level01");

GameAnalytics("addProgressionEvent", "Start", "world01", "stage01", "level01");
Field Type Description Example
progressionStatus enum Status of added progression gameanalytics.EGAProgressionStatus.Start gameanalytics.EGAProgressionStatus.Fail gameanalytics.EGAProgressionStatus.Complete
progression01 string Required progression location. World01
progression02 string Not required. Use if needed. Stage01
progression03 string Not required. Use if needed. Level01
score integer An optional score when a user completes or fails a progression attempt. Remember to set progression02 and/or progression03 if they are not used when using score parameter. 1023

If you do not need progression02 or progression03 do not make any references to these parameters when calling the method. Below you can learn from an example of progression event that uses only progression01 and progression02:



Copy link to clipboard

To add a custom error event call the following function:

gameanalytics.GameAnalytics.addErrorEvent(gameanalytics.EGAErrorSeverity.Debug, "Something went bad in some of the smelly code!");

GameAnalytics("addErrorEvent", "Debug", "Something went bad in some of the smelly code!");
Field Type Description Example
severity enum Severity of error gameanalytics.EGAErrorSeverity.Debug
message string Error message (can be null) “Error when entering level12”




Copy link to clipboard


Please note that custom dimensions and progression filters will not be added on design and error events. Therefore you cannot (at the moment) filter by these when viewing design or error metrics.

To add a design event call the following method:

<!-- Traditional way -->
gameanalytics.GameAnalytics.addDesignEvent(string eventName, float eventValue);
<!-- Command queue -->
GameAnalytics("addDesignEvent", string eventName, float eventValue);


<!-- Traditional way -->
gameanalytics.GameAnalytics.addDesignEvent("BossFights:FireLord:KillTimeUsed", 234);
<!-- Command queue -->
GameAnalytics("addDesignEvent", "BossFights:FireLord:KillTimeUsed", 234);
Field Type Description Example
eventId string The eventId is a hierarchy string that can consist of 1-5 segments separated by ‘:’. Each segment can have a max length of 32. “StartGame:ClassLevel1_5”, “StartGame:ClassLevel6_10”
value float A float event tied to the eventId. Will result in sum & mean values being available. 34.5



command center

Copy link to clipboard



Copy link to clipboard

Product Update – Remote Configs

We are excited to announce the upcoming release of Remote Configs – our new tool that will replace Configs.

Remote Configs will be released in October 2019 with a new user interface and updated SDKs.

You can continue to use the current version of Configs. We will soon be sharing more information and our migration guide.

If you have any questions, please don’t hesitate to reach out.

Register to events for whenever the Config (CommandCenter) is updated with new values:

var myCommandCenterListener = {
    onCommandCenterUpdated: function() {
        // add your code here


To manual check if Configs is ready (has been populated with values) you can call this:

    // the command center is ready, add your code here

To get values out of a populated Config use the following methods:

// Without custom default value (using normal default value)
var value = gameanalytics.GameAnalytics.getCommandCenterValueAsString("key");
// With custom default value
var valueWithCustomDefaultValue = gameanalytics.GameAnalytics.getCommandCenterValueAsString("key", "myDefaultValue");

If the specified key is not found in the Config it will return the default value either “normal” or “custom” default value.

More info Configs please see here


additional calls

Copy link to clipboard


Custom Dimensions

Copy link to clipboard

GameAnalytics support the use of 3 custom dimensions.

  • Custom01
  • Custom02
  • Custom03

During the game it is possible to set the active value for each custom dimension dynamically. Once a dimension is set it will be persisted across sessions/game-start and automatically be added to all event categories. Remember you have to set the custom dimensions before initialzing the SDK (but after setting the available custom dimensions) to be able to add the dimensions to the first session start event.

Setting each custom dimension. To reset a set custom dimension simply just set it to empty string.



GameAnalytics("setCustomDimension01", "ninja");
GameAnalytics("setCustomDimension02", "dolphin");
GameAnalytics("setCustomDimension03", "horde");

GameAnalytics("setCustomDimension03", "");
Field Type Description Example
customDimension string One of the available dimension values set in the configuration phase. Will persist cross session. Set to empty string to reset. ninja

Read more about custom dimensions here.


User Information

Copy link to clipboard

During the game it is possible to set information about your users that will then be annotated to all other events.

  • gender
  • Facebook ID
  • birthyear (age)

These user values will persist cross session/game-launch. Set them to nil to reset.

Set gender.


GameAnalytics("setGender", "Female");

Set birthyear.


GameAnalytics("setBirthYear", 1980);

Set Facebook ID.


GameAnalytics("setFacebookId", "123456789012345");
Field Type Description Example
gender string Gender of player. gameanalytics.EGAGender.Female, gameanalytics.EGAGender.Male
birthYear integer The year the player was born. 1980
facebookId string Facebook Id of the player. 123456789012345

debug & verify

Copy link to clipboard


Copy link to clipboard

The SDK is designed to be as silent as possible and use very few resources. You will therefore not get much information by default in your development console.

We have 2 different debug log types that can be enabled / disabled (at any time).

  • info log
  • verbose log

Info Log

Short messages will be output when enabled explaining when some action is being performed by the SDK. Sometimes cropping text / values to make it more readable.
Enable info log when implementing the SDK – remember to turn it off in production!


GameAnalytics("setEnabledInfoLog", true);
 Info/GameAnalytics: Add DESIGN event: {eventId:someEvent, value:0}
 Info/GameAnalytics: Add DESIGN event: {eventId:someOtherEvent, value:100}
 Info/GameAnalytics: Add ERROR event: {severity:info, message:This is some in}

Verbose Log

Console output when each event is added (all fields) in JSON string format. This is the data being submitted to the GA servers for each event.
Enable verbose log when troubleshooting events.


GameAnalytics("setEnabledVerboseLog", true);

This can result in a lot of text. When troubleshooting/debugging events it is therefore recommended to enable/disable when performing the action that need inspection.

Troubleshooting example.

 // enable verbose log
 // add event you need to troubleshoot / inspect
 gameanalytics.GameAnalytics.addDesignEvent("Some:Event", 100);
 // disable verbose log 

 // enable verbose log
 GameAnalytics("setEnabledVerboseLog", true);
 // add event you need to troubleshoot / inspect
 GameAnalytics("addDesignEvent", "Some:Event", 100);
 // disable verbose log 
 GameAnalytics("setEnabledVerboseLog", false);

Verify Implementation

Copy link to clipboard

Enable the Info Log to verify that events are being sent from your game project without any issues being reported.
Events submitted should register after a minor delay in our realtime dashboard in the GameAnalytics tool.

Realtime Dashboard

Read our in-depth guide to understand what and how to track events


how does it work?

Copy link to clipboard


Session Handling

Copy link to clipboard

Sessions are the concept of a user spending focused time in your game – from game launch to the user leaving the game. A new session automatically starts when a the SDK is initialized, but if s new session needs to be started again during the game’s lifetime it needs to be manually handled. See examples for both start and end session below.

Session Start

  1. Generate new session.
  2. Add a session start event (a “user” event).
  3. Start the periodic activation of submitting queued events.
  4. Next event submit will fix potential missing session_end from earlier sessions.


 // start new session

 // start new session

Session End

  1. Stop the periodic activation of submitting queued events.
  2. Add a session_end event.
  3. Submit queued events.


 // end session

 // end session

If a session end event hasn’t been sent before the game shuts down, the session end will try to be sent next time the game starts again, as the required information for the session end event (for example session length) is stored in a internal database.


Event Queue

Copy link to clipboard

Whenever an event is added (and validated) it will be added to a local database queue.


Every 8 seconds the SDK will start a task for submitting queued events since last submit. This processing is done in a separate low-priority thread that will have minimum impact on performance. The payload is gzipped and will therefore only consume a small amount of bandwidth.


When a device is offline the events are still added to the queue. When the device is online it will submit.


Thread Handling

Copy link to clipboard

Almost every piece of this code is run using a dedicated low-priority serial thread queue to avoid UI lag or sudden performance spikes.

The queue will execute each task sequentially. If the SDK add several tasks to the queue then each will be executed in turn. A task could be adding an event or submitting all queued events.

Consider this example with 3 calls.

// Configure build version
gameanalytics.GameAnalytics.configureBuild("alpha 0.1.0");
// Initialize
gameanalytics.GameAnalytics.initialize("12341234123412341234123412341234", "1234123412341234123412341234123412341234");
// Add Design event

// Configure build version
GameAnalytics("configureBuild", "alpha 0.1.0");
// Initialize
GameAnalytics("initialize", "12341234123412341234123412341234", "1234123412341234123412341234123412341234");
// Add Design event
GameAnalytics("addDesignEvent", "Some:Event");

The configureBuild is required to be called before initialize is completely finished. The design event call is required after initialize is finished. The queuing will make sure that each task is completely finished before proceeding to the next one.


Contact support

We’ll get back to you ASAP.

Report a bug

Let us know more details.