This tutorial will show you how to use scripting in Atomic to capture analytics events in your prototype and send them to Google Sheets via a simple webhook. It will step you through:

  • Adding our sample tracking JavaScript to your prototype
  • Defining variables which tell the tracking function about your prototype
  • Adding a single line of JavaScript to the places/things you want to capture event data for
  • Setting up a (2-step) Zapier Zap to catch the data your prototype sends, then send your analytics data to a Google Sheet
  • Adding a new page to the start of your prototype where your prototype's reviewers can switch tracking on/off and provide their name (to send with their analytics events)

To get this working, you'll need:

Before you begin:

Opening the browser console when testing scripts helps you easily discover code errors and makes troubleshooting faster. We also recommend, if you're a Mac user, installing Atomic Assistant

Choose a prototype to work with

If you have an existing prototype you want to add analytics to, open it in the editor. If not copy this sample prototype to your account then open it in the editor.

Add a way to turn tracking on/off

The sample script consists of a tracking function wrapped in an if statement. The if statement exists so you can easily turn tracking on or off for a given session, which can help you avoid junking up the data with unwanted events. The if statement looks at the value of a project variable named trackAnalytics. If that exists and has a value of on  then tracking events will be sent. So we need to create this variable, and give it a default value for your prototype.

With your prototype open in the editor, type v to open the project variables list then add a new variable named trackAnalytics and give it a default value of on:

If you want to give your reviewers control over tracking (optional):

You will need to build a way for reviewers to change the value of the trackAnalytics variable. We suggest you make/add a switch that is presented to reviewers on the first page of your prototype, and add two component change actions so when they toggle the switch, the value of trackAnalytics is changed from off  to on, like this:

In this above example, one component change action sets the value of trackAnalytics  to on, the other sets it to off.

If you are working with a copy of our sample, it already has a switch component on Page 1 with component change actions configured to change the value of trackAnalytics. If you are working with your own prototype, you may still want to copy just this switch component sample and add it to your project, then add it to your prototype. 

Here's how this ends up in our sample prototype:

Add a way to collect your reviewer's name (optional)

The tracking function code we provide is set up to expect a project variable named fullName, to help you identify the origin of analytics events. The script will work fine without it, but if you do want to pass a name value with tracking events, you'll need to declare the fullName variable and create a way for your users to update that with their details. 

With your prototype open in the editor, type v  to open the project variables list, then add a new variable named fullName and leave default value empty:

Next, close the variables list and use the toolbar to add a new Text Input to the first page in your prototype. Then, with the input element selected, over in the element properties, link the fullName variable to it by changing the content dropdown to: fullName:

Now when a reviewer edits this input, the value they enter will be saved in the variable and automatically picked up by the tracking script. 

Here's an example of how in Atomic's own demo-prototype, we have a setup page discretely tucked away:

Add the tracking script to your prototype

Now it's time to copy our tracking script into your prototype. 

If you have added a setup page to your prototype during the steps above (to capture your reviewer’s name and a on/off switch, navigate now to the next page in your prototype (i.e. the second page), otherwise, navigate to Page 1. With nothing selected on your canvas, add a new Page Action, and configure it to wait 0ms before evaluating a Script Expression.

Next, paste the sample code into the script expression code block:

//  Session-level config
const PROTOYTYPE_ID = "My Prototype Name"; // Unique name for this prototype
const USER_ID = $p.fullName; // Value is optional
const SESSION_ID = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
//  Tracking function that sends events to the Zapier webhook:
trackEvent = function (proj_vars, event_name, location, event_type, event_detail){
    if (proj_vars.trackAnalytics == "on"){

        // Declare the variable that will hold the event data
        let eventData = {};
        eventData.session_id = SESSION_ID;
        eventData.prototype_id = PROTOYTYPE_ID;
        eventData.user_id = USER_ID;
        eventData.timestamp = new Date();
        eventData.message_id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
        eventData.event_name = event_name;
        eventData.location = location;
        eventData.event_type = event_type;
        eventData.event_detail = event_detail;
        // Now send that data to Zapier
        // Add the URL provided by zapier in the row below:
            method: "post",
            body: JSON.stringify(eventData)
        }).then(response => response.json()).then(data => {
            // After Zapier responds, do these things:
            console.log("Event logged to Zapier:");
            console.log("Response was", data);

When you've done this, your action’s properties should look like this:

Create a Google Sheet to hold analytics data

Open our sample Google Sheets template and make a copy in your own account: 

Set up your Zapier webhook

We now need to configure where to send data to. Create your Zapier account if you don't have one already, and create your first "Zap". 

Here’s a short video of the Zapier setup steps. Each step is outline below.

  • Click the Make a Zap button in the header of your Zapier account.
  • Scroll down the list of trigger apps, and choose the "Webhooks by Zapier" option. 
  • Choose to create a "Catch Hook" as the trigger.
  • Skip the step about creating a picking off a child key by selecting continue.
  • When Zapier presents you with your new custom webhook URL, copy it to the clipboard
  • Return to Atomic, locate in the script you’ve pasted in, scroll down towards the bottom and replace ADD YOUR ZAPIER WEBHOOK URL HERE with your custom webhook URL.

At this stage, Zapier requires you to send a test request from Atomic. To do this, we need to create a test event tracking call in your prototype. 

  • On the same page of your prototype that you added the main script, add another timer page action that runs after, say, 100ms. Paste this line in as a script expression:
trackEvent($p, "New Session", SELF, "Track", "Prototype was reviewed"); 
  • Now we’re ready to send our test to the Webhook.  Open your browser console so when you preview your prototype, you can spot any errors that might occur.
  • Open your prototype in preview mode. The above script should have called the tracking function and sent your first test to Zapier. Check your console to see the confirmation message.
  • Return to Zapier and click the Ok I did this button, Zapier will confirm that it has received the event and you'll see a link to view your hook, click it to see the details of your hook.
  • Click continue.  Now it’s time to connect Zapier to Google Sheet.
  • You should now be editing the Choose App step of Step 2 in your zap.
  • In the search bar, type “sheets” and select Google Sheets from the list of apps. 
  • Next, select the option to Create Spreadsheet Row then Save + Continue.
  • Follow the steps to Connect an account and connect Zapier to Google Sheets, then Save + Continue.
  • In the next step, expand the list of spreadsheets Zapier can see, and choose the spreadsheet you copied in the earlier steps.
  • Next, select the Raw worksheet from the worksheet dropdown.
  • Zapier will advance you to the Edit Template step, where you can now map the fields from your test hook, to the columns on the Raw worksheet of the sheet you’ve just connected. 
  • When your fields are all mapped, click the Test button. 
  • When Zapier confirms the test row has been added, open the Google Sheet, on the Raw tab, to see the new row for yourself. 
  • There’s a tab in the Google Sheet named Report which provides a simple way to filter from the Raw sheet, which is handy when your Raw sheet is filled with data from multiple reviewers and different prototypes. 
  • Switch to the Report tab and in the drop-downs in the header, choose from the Name, and then Session ID fields. The corresponding events data from the Raw tab will now be pulled into the Report tab for you to view.

Now that's done, any events sent to Zapier will appear as new rows in the Raw sheet of your Google doc.

Add tracking calls to the things you want to track

The final (and most important step!) is to work through your prototype, and add a one-line script in the places you'd like events to be tracked. 

Work your way through your prototype adding this tracking script into any script expression block where you want a tracking event to be sent. Like this:

Tracking an new analytics event

Any script expression in your document that contains the following one-line script, will cause an analytics event to be tracked, so you can track things when components change state, when pages are loaded, when variables change, or any other scenario in which you can trigger a script expression, go nuts!

trackEvent($p, name, location, category, detail);


Each argument passed to the function will provide context about that specific request, so it’s important to make sure the example script is customised for each scenario. 

$p  — Always pass the $p. as the first argument (Required) 

name  — String representing the name for this event (Required)
Example: “Clicked Submit”

location  — String/array describing where in the doc the event occurred (Optional)
Example: SELF

category  — String representing a category to group this event by (Optional)
Example: “Direct user interaction”

detail  — String with more context or detail about this event (Optional)
Example: “Dark blue button variation”


In most cases, your code will look like this:

trackEvent($p, "Clicked submit", SELF , "Direct user interaction", "Dark blue button variation");

If you are leaving some fields empty, but providing values for arguments after the empty slot, leave the slot blank like the third argument in this:

trackEvent($p, "Viewed Screen", SELF ,, "A main page in the prototype was viewed");

If you only want to pass the first N arguments, you can then just omit the rest and the function will work fine, like this.

trackEvent($p, "Viewed Screen", SELF);

Tip: SELF is a special variable that always contains the path (in the form of an array), from the root of your prototype, to the location of the script where SELF was called. Using SELF as the argument for location when calling the trackEvent function is a simple way to feed the function the precise location of the script that made the function call. You can, however, pass any string as the location argument. 

Congratulations, you’ve just made a flexible, simple analytics system in Atomic!

Have suggestions for how we can improve this tutorial? Please give us feedback or suggestions for other tutorials you’d like to see. 

Did this answer your question?