- Help Center
- Configuration
- SPA Testing
-
Getting Started
-
Configuration
- Targeting
- Split URL
- Product Testing
- Full Stack
- Experiment Management
- CSP Configuration
- Experiment Execution
- Reports
- Exit Popups
- GTM Integration
- Troubleshooting
- Performance Optimization
- Event-Triggered Changes
- Holdout Groups
- Split URL Pages
- URL Parameters
- DataLayer
- Menu Configurations
- Traffic Exclusion
- Experiment Scheduling
- Dynamic Element Changes
- Price Targeting
- Experience Scheduling
- Privacy
- Hash Changes
- Async Tracking
- Selective Installation
- CSS Selectors
- Vue.js Integration
- Page Content
- Multipage Split URL
- Organic Traffic
- Visual Editor
- Server-Side Testing
- Traffic Bucketing
- GDPR Warnings
- Statistical Confidence
- Browser Privacy
- Query Parameters
- Embedded Videos
- Tracking Code Execution
- Simultaneous Experiments
- Tags
- Deployments
- Disable Testing
- Locations
- Programmatic Bucketting
- Query Parameter Handling
- Convert Library
- Variation Previews
- Experiment Editing
- Opt-Out Script
- Data Reset
- Body Hiding
- Visit-Specific Variations
- Variation Styling
- Preview Issues
- Variation Editing
- Full-Site Testing
- Blinking Variations
- Cross-Domain Cookies
- Regex Support
- Conversion Tracking
- SPA Testing
- Project Setup
- Cross-Domain Tracking
- Geo-Targeting
- Analytics Tools
- Campaign Tags
- Previewing
- IDs
- Query String Targeting
- Bounce Rate Goals
- Bot Filtering
- Query String Variables
- Custom Audiences
- Redirects
- Baseline
- Tracking Code Location
- Secure Cookies
- AngularJS
- Cloudflare
- Code Installation
-
Track Goals
- Form Tracking
- Cookie Management
- iFrame Click Tracking
- Performance Optimization
- Revenue Tracking
- Interaction Goals
- Form Submissions
- Advanced Goals
- Lazy Loading
- Multi-Conversions
- URL Parameters
- Bounce Rate Goals
- DataLayer Integration
- Scroll Depth
- Social Interactions
- Page Views
- Marketo Forms
- Feature Analysis
- AJAX Forms
- Revenue Tracking via GTM
- Order Outliers
- Cumulative Revenue
- Goal Templates
- Adding Revenue Goals
- JS-Based Goals
- Goal Basics
- Google Analytics Goals
- Social Sharing
- Dynamic Goals
- Typeform Integration
-
Target Visitors
- Geolocation
- Interaction Goals
- Goal-Based Targeting
- Weather Targeting
- Cookie-Based Targeting
- Page Visits
- Audience Management
- Audience Segmentation
- Experiment Targeting
- Advanced Audience Creation
- Audience Templates
- Audience Creation
- Data Layer Integration
- Manual Activation
- JavaScript Conditions
- Device Targeting
- Language Targeting
- IP-Based Exclusion
- Visitor Management
- Page Tagging
- Cookies
-
Troubleshooting
- Google Warnings
- Visual Editor
- HTTPS Content
- Logs
- Support Options
- Bootstrap
- Cookie Blocking
- Change History
- Mobile Debugging
- AdWords
- Bot Exclusion
- Domain Issues
- Cloudflare Issues
- Monitoring
- Cloaking Penalties
- Goal Editor Issues
- Variations
- Snippet Performance
- Changes Not Saved
- Blocked Visual Editor
- Goal Testing
- Visual Editor Browsing
- Experiment Issues
- Installation Verification
- Data Leak Prevention
- Usage Limits
- Experiment Previews
- GA4 Revenue
- Chrome Debugger Logs
- SPA Errors
- Checkout JSON Error
-
Analyze Results
-
Integrations
- Google Analytics
- Cookie Consent Platforms
- Microsoft Clarity
- Plausible
- Marketo
- HubSpot
- Tealium
- Smartlook
- Klaviyo
- Salesforce CRM
- FullStory
- Snowplow Analytics
- Webflow
- GA4 Roles
- Amplitude
- Segment
- React
- BigCommerce
- WooCommerce
- Active Campaign
- Google Tag Manager
- Mixpanel
- Zapier
- Inspectlet
- Crazy Egg
- LanderApp
- Unbounce
- Instapage
- Drupal
- PrestaShop
- Magento
- Roistat
- Piano Analytics
- Heap Analytics
- Kissmetrics
- Mouseflow
- Adobe Analytics
- Clicky
-
Account Management
-
Developers
-
What's New
-
Common Questions
-
Shopify
Running Experiments on Single Page Apps
THIS ARTICLE WILL HELP YOU:
SPA testing options
Important
If you use the latest version of the Convert script, none of what is described in this article is relevant, as it has built in and optimized features for SPAs.
Experiments on Single Page Applications SPAs usually need to be handled differently than other experiments. Because the Convert script usually cannot read the URL that a website visitor is navigating, it cannot trigger experiments with standard methods.
Firstly you need to install the Convert tracking code as described in this article.
However, Convert provides other methods for triggering experiments within single-page frameworks:
1) Triggering Polling
Polling is the process by which the experience conditions are tested to determine if said experience should be triggered. This includes monitoring the visitor URL, audience conditions or JavaScript conditions to run the test. Polling is usually triggered by Convert when a new page is loaded. On SPAs, usually, no new pages are loaded on the web app. In that case, you would need the following code to start the polling (do not use this code yet.):
window._conv_q = _conv_q || [];
window._conv_q.push(["run","true"]);
You should determine what the best event on your SPA would be to trigger the above code.
However, this is a generalized code snippet that would trigger the Convert polling on any framework without a specific integration. Add the following code to the Project Configuration > Global Javascript section.
console.log('SPA/Convert Code in Global Project Javascript executed');
if (!window.globalExecutedTs) {
// create a proxy to the pushState function
const pushStateProxy = new Proxy(window.history.pushState, {
apply: function(target, thisArg, argumentsList) {
// execute your code here
console.log('History updated: ' + argumentsList[2]);
console.log('Convert activated from pushstate');setTimeout(() => { //
console.log('Current URL to be read by Convert:'+location.href);
_conv_q = window._conv_q || [];
_conv_q.push(["run", "true"]);
}, "100");
// call the original pushState function to update the history
return Reflect.apply(target, thisArg, argumentsList);
}
});
// override the pushState function with the proxy
window.history.pushState = pushStateProxy;
}
Here is another one that checks the actual URL value every 100ms. This is a configurable time. Use it if the previous one does not work:
console.log('SPA/Convert Code in Global Project Javascript executed');
if (!window.globalExecutedTs) {
function checkURLchange(){
if((window.location.href + window.location.hash) != oldURL){
oldURL = (window.location.href + window.location.hash);
console.log('URL Changed and will fire Convert');
window._conv_q = _conv_q || [];
window._conv_q.push(["run", "true"]);
}
}
window.globalExecutedTs = true;
var oldURL = (window.location.href + window.location.hash);
setInterval(checkURLchange, 100);
}
2) Use JavaScript Conditions in the Locations
Because the Convert script cannot read URL changes in a SPA, you should use a JavaScript condition instead of a URL match condition to trigger an experiment. You can find a more thorough explanation of how to do this in the following article.
3) Manually Activate an Experiment
You can trigger experiments manually after you determine that a certain flow has happened. In this method, Locations and Audience conditions will still be tested after triggering the polling with code. Please read the following article about how this can be done.
With the above 3 methods, you should be able to trigger experiments at the right moment in an Angular app.
** Be aware that changes triggered by the experiment will not be reset as they would be with a normal web page. For example, if you change a page element after a menu element has been clicked, clicking on the home page menu element will not reset that change. You will have to undo the element with code. You may want to do this by (for example) adding code to the Custom JavaScript area within the Visual Editor.
4) Goals checked through polling
The majority of goals are checked by Convert throughout the polling process. This polling process occurs when a page is initially loaded or called on item 1. However, with SPAs such as Angular, page loading does not occur when navigating through the application. For these types of scenarios, Convert has a specific function to call to activate the polling for monitoring goal conditions. The code for calling it is the following:
window._conv_q = window._conv_q || [];
window._conv_q.push(['recheck_goals']);
Please don't hesitate to have a chat with us via any of the Support channels if you have any further questions about configuring these types of applications with Convert.
keyword: spa