Global scope for Javascript variables in Storyline

May 02, 2022

As Storyline publishes all code and variables to separate functions in the user.js file the scope for individual variables is local. The solution i show here creates a global scope for functions and variables so you can reuse your Javascript code and variables anywhere in a Storyline project.

Basically i make use of a WebObject to add an external Javascript to Storyline. In that script variables are stored globally so you can reuse them anytime. Also with this solution you can add any custom function to the globalScript.js file. Those functions can then be called from any spot in Storyline.

Lets see it working first.
In this Storyline you can enter 2 values. A property name and its value. Those will be saved in a Javascript object and can be called with a global function or directly. When adding your first one... it shows in the textfield on the left... then you can continue to the next slide...and do the same... either edit one of the added values...or add a new one.

The function iterateObject(_obj,_desiredoutput); you can use to get your variables and values. Offcourse the argument _obj is for your Object in Javascript. In this case  its 'globObj', but you can add as many as you want and customize them. The argument _desiredoutput is for what you want returned. Default that is a string, but you can choose to get an array.

Alright some more info on how it works. As you can see in the Storyline file i use a separate scene for the WebObject that loads the Javascript file(s).
As you can see i use subfolders for my Javascript files. Nothing more then the empty index.html and the globalScripts.js in its own subfolder for the WebObject.
To load the Javascripts files into Storyline i use a Javascript trigger on the start of the timeline. This is probably best added to a Master Slide and ensure its only loaded when the variable 'javascriptsLoaded' is False.
When changing anything to the 'globalScripts.js' or the WebObject you would need to change 2 variables in the script. amountOfLibs and webObjectURL. The latter offcourse refers to the folder Storyline publishes the webObject to. And you would need to publish and check the name of the folder when changing anything.
Then you can call the functions from the 'globalScript.js'. In this sample i only added 2 functions. One to set the variables and one to get them again. Both work on any spot in the Storyline. After the Javascript is loaded you can set and get variables from anywhere in your Storyline.
Do hope this is usefull for some of you. 

7 Replies
Jürgen Schoenemeyer

if you wan't to use small solutions for global variables in javascript - use window-variables (storyline is technical a single-page application)


javascript trigger 1:

function hallo(){
window.myText = "hallo";

javascript trigger 2:

function printHallo(){
console.log( window.myText );

normaly window variables are not used*, the normal javascript would be

var myText;

function hallo(){
myText = "hallo";

function printHallo(){
console.log( myText );

the result is the same, but this it is not possible in a trigger javascript


* as a developer you should not use such things - global variables are nasty. If you are not careful, they can cause big problems. Normally you encapsulate variables. 

steve paradis

Hello Guys,

My personal solution is to use a webObject on the first scene, with sessionStorage.

I do load a webObject (first slide and off stage). the code in the index.html is simply :

sessionStorage.setItem("msg_EN","Hello world!");
sessionStorage.setItem("msg_FR","Bonjour le monde!");
sessionStorage.setItem("msg_ES","Hola mundo!");

These become available for each slides even for other webObjects :

var player = GetPlayer();

If you care about making the variables more "private", you can always use base64 encode/decode, here is the function I use:

function encodeB64(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
function toSolidBytes(match, p1) {
return String.fromCharCode('0x' + p1);

function decodeB64(str) {
return decodeURIComponent(atob(str).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);