Trackingplan Documentation
Trackingplan Documentation
Environments

Environments

What is Trackingplan

OverviewOverview

The Trackingplan Way

AutomonitoringAutomonitoring
EventsEventsPropertiesPropertiesUser AttributesUser AttributesPagesPagesAcquisitionAcquisitionPlatform MetricsPlatform Metrics
Automated Alert SystemAutomated Alert System
Warnings & UpdatesWarnings & UpdatesPixel MonitoringPixel MonitoringPrivacy MonitoringPrivacy MonitoringNaming Conventions MonitoringNaming Conventions MonitoringDiscover ReleasesDiscover ReleasesData ValidationData ValidationDigestsDigests

Getting Started

Installing TrackingplanInstalling Trackingplan
For WebsitesFor WebsitesWebhooksWebhooksFor AppsFor AppsFor ssGTMFor ssGTM
Post-Install Warm-UpPost-Install Warm-Up

Inside Trackingplan

DashboardDashboard
SearchSearchHealth SummaryHealth SummaryStarred ItemsStarred ItemsReportsReports
Data ExplorerData ExplorerTracks ExplorerTracks ExplorerRoot Cause AnalysisRoot Cause AnalysisPresence MapPresence MapAdvanced ReportsAdvanced ReportsSession FinderSession Finder
Privacy ReportPrivacy ReportChange HistoryChange HistorySettings & MembersSettings & Members
DestinationsDestinations

How to…

Manage WarningsManage Warnings
Mute WarningsMute WarningsDebug WarningsDebug WarningsAttributionAttributionCustomize WarningsCustomize Warnings
Ensure PrivacyEnsure Privacy

Privacy ReportPrivacy Report

Cookies & ConsentCookies & ConsentConsent Mode Consent Mode Privacy by DesignPrivacy by Design
Marketing ObservabilityMarketing Observability
Campaign ValidationCampaign ValidationPixels Summary Pixels Summary
Enhance CollaborationEnhance Collaboration
SharingSharingNotes & LabelsNotes & LabelsPersonalized DigestsPersonalized Digests
Extend detectionExtend detection
TagsTagsChrome ExtensionChrome ExtensionData Layer Audit Data Layer Audit Explore your DataExplore your DataEnvironmentsEnvironments
Multi-Account ManagementMulti-Account Management
Plans OverviewPlans OverviewJSON Export/ImportJSON Export/ImportSplit DestinationsSplit Destinations

Others

Google Spreadsheet AppGoogle Spreadsheet AppLooker Studio ConnectorLooker Studio ConnectorOmnibug ExtensionOmnibug ExtensionTrackingplan Public APITrackingplan Public APISupported Trackers Supported Trackers SDK UpdateSDK UpdateRelease NotesRelease NotesPrivacy and SecurityPrivacy and Security

Environments

💡
Besides production, you can run Trackingplan on other environments – like staging or development – to detect problems before any release.

Trackingplan allows you to specify your “environment” dynamically at run-time. This way, you can:

  • Differentiate between the data and specifications you have in one environment and another.
  • Compare environments to detect mistakes before they reach production. For example, compare staging data to your master specification baseline to capture bugs or regressions before they reach production.
  • Create as many environments as you need. The most common setup is having ~3 environments (production, staging, and development) to check changes before a release. However, some Trackingplan users even have one environment per branch or automated test, allowing them to detect errors with more granularity.

Setting up Trackingplan for different environments

Trackingplan supports complex deployment setups with custom preproduction environments.

You just have to modify this init according to your specifications and your own TP_ID and add it at the top of the <head> section of your site (instructions here), or include it as a new Google Tag Manager Script (instructions here).

<script type="text/javascript">
(function(){function a(a){var b={method:"POST",endpoint:"TRACKINGPLAN",payload:JSON.stringify(a)};m(b)}function b(a){if($.includes("img"))try{f(a)}catch(a){E(a)}if($.includes("xhr"))try{h(a)}catch(a){E(a)}if($.includes("beacon"))try{i(a)}catch(a){E(a)}if($.includes("form"))try{l(a)}catch(a){E(a)}if($.includes("ws"))try{k(a)}catch(a){E(a)}if($.includes("fetch"))try{j(a)}catch(a){E(a)}}function c(){var a=d();if(null!==a&&!Y)return!1;var b={landing:document.location.href,referrer:document.referrer};return H.setItem("_trackingplan_initial",JSON.stringify(b)),!0}function d(){return JSON.parse(H.getItem("_trackingplan_initial"))}function e(){try{if(H.setItem("_tp_t","a"),"a"!==H.getItem("_tp_t"))return!1;if(H.removeItem("_tp_t"),"function"!=typeof navigator.sendBeacon)return!1}catch(a){return!1}return!0}function f(a){var b=a.Object.getOwnPropertyDescriptor(a.HTMLImageElement.prototype,"src").set;a.Object.defineProperty(a.HTMLImageElement.prototype,"src",{set:function(a){return 2048<a.length?b.apply(this,arguments):(m({method:"GET",endpoint:a,protocol:"img"}),b.apply(this,arguments))}});var c=a.HTMLImageElement.prototype.setAttribute;a.HTMLImageElement.prototype.setAttribute=function(a,b){if("src"==a.toLowerCase()){if(b.length>2048)return c.apply(this,arguments);m({method:"GET",endpoint:b,protocol:"img"})}return c.apply(this,arguments)}}function g(a){var b=a;try{b instanceof FormData&&(b=JSON.stringify(Object.fromEntries(b)))}catch(a){}return b}function h(a){var b=a.XMLHttpRequest.prototype.open,c=a.XMLHttpRequest.prototype.send;a.XMLHttpRequest.prototype.open=function(a,c){return this._tpUrl=c,this._tpMethod=a,b.apply(this,arguments)},a.XMLHttpRequest.prototype.send=function(a){var b=g(a);return m({method:this._tpMethod,endpoint:this._tpUrl,payload:b,protocol:"xhr"}),c.apply(this,arguments)}}function i(a){var b=a.navigator.sendBeacon;a.navigator.sendBeacon=function(a,c){if(2048<a.length)return b.apply(this,arguments);var d=g(c);return m({method:"POST",endpoint:a,payload:d,protocol:"beacon"}),b.apply(this,arguments)}}function j(a){var b=a.fetch;a.fetch=function(a,c){if(2048<a.length)return b.apply(this,arguments);var d="GET",e=null;return void 0!==c&&(void 0!==c.method&&(d=c.method.toUpperCase()),void 0!==c.body&&(e=g(c.body))),m({method:d,endpoint:a,payload:e,protocol:"fetch"}),b.apply(this,arguments)}}function k(a){var c=a.WebSocket;a.WebSocket=function(d,a){return a?new c(d,a):new c(d)};var b=c.prototype.send;c.prototype.send=function(a){({method:"WS",endpoint:this.url,payload:a,protocol:"ws"});return m({method:"WS",endpoint:this.url,payload:a,protocol:"ws"}),b.apply(this,arguments)},a.WebSocket.prototype=c.prototype}function l(a){a.addEventListener("submit",function(a){try{var b=a?a.target:this,c={method:b.method,endpoint:b.action,payload:JSON.stringify({location:I.location.href,form_id:b.id,method:b.method,form_data:Object.fromEntries(new FormData(b))}),protocol:"form"};m(c)}catch(a){}},!0)}function m(a,b){setTimeout(function(){try{var c=C(a);if("TRACKINGPLAN"==a.endpoint&&(c="trackingplan"),!c)return;var d=A();return!1===d?(ea.push(a),E({m:"Pre queued, queue length = "+ea.length}),setTimeout(y,T),!1):(null===ha&&(ha=u(),ia=JSON.stringify(ha).length),!r(V,d))?(E({m:"Request ignored (sampling)",mode:V,dict:d}),!0):(n(s(a,c)),"function"==typeof b&&b(),!0)}catch(b){F({m:"Trackingplan process error",error:b,request:a})}},0)}function n(a){aa(a);var b=JSON.stringify(a);if(2e5<b.length&&E({m:"Track Too big, ignored: "+b.length}),b.length+2+ia>W)return q("["+b+"]",P),void E({m:"Track > Batch Size: "+b.length});var c=fa.length+b.length+ia;c>W&&(E({m:"Batch reaching limit: "+c}),o(P)),c=fa.length+b.length+ia,E({m:"Queue len: "+c,rawTrack:a}),0!==fa.length&&(fa+=","),fa+=b}function o(a){if(0!=fa.length){var b=fa;fa="";var c={requests:JSON.parse("["+b+"]"),common:ha};q(c,a)}}function p(){var a=R+M;return ca&&(a+="?debug=true"),a}function q(a,b){return("function"==typeof ba&&(a=ba(a)),E({m:"Sent",payload:a}),Z)?void E("Not sending, is dry run"):void("xhr"===b?function(a){var b=new XMLHttpRequest;b.open("POST",p(),!0),b.onreadystatechange=function(){if(4===b.readyState)try{E({m:"Parsed",response:JSON.parse(b.response)}),_(a,b.response)}catch(a){}},b.send(a)}(JSON.stringify(a)):"beacon"===b?function(a){navigator.sendBeacon(p(),a)}(JSON.stringify(a)):void 0)}function r(a,b){switch(a){case"user":return 1===b.isSampledUser;case"track":return Math.random()<1/b.sampleRate;case"all":return!0;case"none":default:return!1;}}function s(a,b){return{provider:b,request:{endpoint:a.endpoint,method:a.method,post_payload:a.payload||null,protocol:a.protocol,href:I.location.href}}}function t(){return D({hostname:I.location.hostname,user_agent:navigator.userAgent,load_url:ga},d())}function u(){return{context:t(),tp_id:M,source_alias:O,environment:N,sdk:ja.sdk,sdk_version:ja.sdkVersion,sampling_rate:A().sampleRate,debug:Q}}function v(){try{for(var a=window.performance.getEntriesByType("resource"),b={},c=[],d=0;d<a.length;d++){c.push(a[d].name);var e="",f=a[d].name.replace(/(^\w+:|^)\/\//,""),g=f.split("?"),h=g[0];g=h.split("/"),e=1<g.length?g[0]+"/"+g[1]:g[0];var j=e;b.hasOwnProperty(j)||(b[j]=0),b[j]++}return b}catch(a){return null}}function w(){for(;ea.length;){var a=ea.shift();m(a)}}function x(a,b){var c=Object.prototype.hasOwnProperty;return c.call(a,"environment_rates")&&c.call(a.environment_rates,b)?a.environment_rates[b]:a.sample_rate}function y(){if(!da){var b=new XMLHttpRequest,c=S+"config-"+M+".json";b.onreadystatechange=function(){if(4==this.readyState)try{z(x(JSON.parse(this.responseText),N)),a({event_name:"new_dau"}),w()}catch(a){}da=!1},b.open("GET",c,!0),da=!0,b.send()}}function z(a){if(!1===a)return H.removeItem("_trackingplan_sample_rate"),H.removeItem("_trackingplan_sample_rate_ts"),void H.removeItem("_trackingplan_is_sampled_user");var b=Math.random()<1/a?1:0;E({m:"Trackingplan sample rate = "+a+". isSampledUser "+b}),H.setItem("_trackingplan_sample_rate_ts",new Date().getTime()),H.setItem("_trackingplan_sample_rate",a),H.setItem("_trackingplan_is_sampled_user",b)}function A(){var a=H.getItem("_trackingplan_sample_rate_ts");return null!==a&&(parseInt(a)+1e3*U<new Date().getTime()?(E({m:"Trackingplan sample rate expired"}),z(!1),!1):{sampleRate:parseInt(H.getItem("_trackingplan_sample_rate")),isSampledUser:parseInt(H.getItem("_trackingplan_is_sampled_user"))})}function B(a,b){if(null===a||null===b)return!0;if("/"===a[0]){var c=new RegExp(a.slice(1,-1));return c.test(b)}return-1!==b.indexOf(a)}function C(a){var b=a.endpoint,c=a.payload;if("string"==typeof b||b instanceof String){for(var d in L){var e=d.split("%"),f=e[0],g=2===e.length?e[1]:null;if(B(f,b)&&B(g,c))return L[d]}return!1}}function D(b,c){for(var d in c)b[d]=c[d];return b}function E(a){Q&&J.log("TP "+M,a)}function F(a){I.console&&J.warn&&J.warn(a)}function G(){function a(){for(var a=document.getElementsByTagName("IFRAME"),b=0;b<a.length;b++)d(a[b])}function c(a){try{return!!a.contentDocument}catch(a){return!1}}function d(a){try{c(a)&&(b(a.contentWindow),E("Intercepted frame "+a.id))}catch(a){}}function e(){var a=new MutationObserver(function(a){a.forEach(function(a){a.addedNodes.forEach(function(a){"IFRAME"==a.tagName&&d(a)})})});a.observe(document,{subtree:!0,childList:!0,attributes:!1,characterData:!1}),setTimeout(a.disconnect(),4e3)}"complete"===document.readyState?(a(),e()):document.onreadystatechange=function(){"complete"===document.readyState&&(a(),e())}}var H=localStorage,I=window,J=console;if(I.Trackingplan)return void F("Trackingplan snippet included twice.");var K={"google-analytics.com":"googleanalytics","analytics.google.com":"googleanalytics","api.segment.io":"segment",segmentapi:"segment","seg-api":"segment","segment-api":"segment","/.*api-iam.intercom.io/messenger/web/(ping|events|metrics|open).*/":"intercom","api.amplitude.com":"amplitude","ping.chartbeat.net":"chartbeat","/.*api(-eu)?(-js)?.mixpanel.com.*/":"mixpanel","trk.kissmetrics.io":"kissmetrics","ct.pinterest.com":"pinterest","facebook.com/tr/":"facebook","track.hubspot.com/__":"hubspot","/.*.heapanalytics.com/(h|api).*/":"heap","/.*snowplow.*/":"snowplow","/.*ws.*.hotjar.com/api/v2/client/ws/%identify_user":"hotjar","/.*ws.*.hotjar.com/api/v2/client/ws/%tag_recording":"hotjar","klaviyo.com/api/track":"klaviyo","app.pendo.io/data":"pendo","matomo.php":"matomo","rs.fullstory.com/rec%8137":"fullstory","rs.fullstory.com/rec%8193":"fullstory","logx.optimizely.com/v1/events":"optimizely","track.customer.io/events/":"customerio","alb.reddit.com/rp.gif":"reddit","px.ads.linkedin.com":"linkedin","/i/adsct":"twitter","bat.bing.com":"bing","pdst.fm":"podsights"},L={},M=null,N="PRODUCTION",O=null,P="xhr",Q=!1,R="https://tracks.trackingplan.com/v1/",S="https://config.trackingplan.com/",T=0,U=86400,V="user",W=6e4,X=20,Y=!1,Z=!1,$=["img","xhr","beacon","ws","fetch"],_=function(){},aa=function(){},ba=function(a){return a},ca=!1,da=!1,ea=[],fa="",ga="",ha=null,ia=0,ja=I.Trackingplan={sdk:"js",sdkVersion:"1.11.0",setOptions:function(a,b){b=b||{},M=a,N=b.environment||N,O=b.sourceAlias||O,P=b.sendMethod||P,L=D(K,b.customDomains||{}),Q=b.debug||Q,R=b.tracksEndPoint||R,S=b.configEndPoint||S,T=b.delayConfigDownload||T,U=b.sampleRateTTL||U,V=b.samplingMode||V,W=b.batchSize||W,X=b.batchInterval||X,Y=b.alwaysSendNewUser||Y,Z=b.dryRun||Z,$=b.intercept||$,_=b.onSubmit||_,ca=b.parse||ca,aa=b.onQueue||aa,ba=b.onBeforeSubmit||ba,E({m:"TP options updated",options:b})},init:function(d,f){f=f||{};try{if(!e())throw new Error("TP Not compatible browser");if(null!==M)throw new Error("TP Init already happened");ja.setOptions(d,f),ga=I.location.href,b(window),$.includes("frame")&&G(),document.addEventListener("visibilitychange",function(){"hidden"===document.visibilityState&&o("beacon")}),I.addEventListener("pagehide",function(){o("beacon")}),c()&&a({event_name:"new_user"}),a({event_name:"page_load"}),setTimeout(function(){a({event_name:"pixels",properties:{pixels:v()}})},1e4),setInterval(function(){o(P)},1e3*X),E({m:"TP init finished",options:f})}catch(a){F({m:"TP init error",error:a})}}}})();
	Trackingplan.init("your TP_ID", {
		'environment': 'how you want to name the environment (e.g. testing, staging)',
	});
</script>

As you can see, the installation process is the same as the one you carried out when installing Trackingplan. The only thing that changes here is the environment variable within the init provided above.

  • Note: The same applies for iOS and Android, where you will only need to set the environment variable in the init.

After this easy installation, you’ll be able to see it documented inside Trackingplan’s Dashboard, or through automated digests (e.g. reporting results on daily or weekly development cycles).

  • Note: To integrate different environments using Segment, just add the query parameter &environment=<environment_name> to your webhook endpoint to have the desired behavior. For the production environment, you should use PRODUCTION.

Integrating your staging and testing environments and comparing them to your baseline allows you to see the differences between one release and the next, detecting broken events or schemas before releasing them. Any existing automated QA you have implemented, such as functional or non-functional regression testing (e.g. with Cypress), will stress your analytics under the watch of our system.

As a result, you can also cover the analytics service integrations in your existing release testing by simply integrating Trackingplan without changing your feature or testing code in any way.

← Previous

Explore your DataExplore your Data

Next →

Multi-Account ManagementMulti-Account Management