I have recently been doing some work with FXM and as part of that a large portion of that work has been with using FXM on single page applications(SPA). While the Sitecore FXM api provides functions for pushing events it doesn't provide a function for refreshing the context of the application as a whole. The following is the approach that I have used on a recent project.
I should firstly caveat the above with the fact that this is based on Sitecore 8.0 Update 5 and there is a fair chance that this will approach will have been superseded in the future.
If you set FXM up on a site hosting a single page application by default you will be able to send down content and track interactions on the first screen. But when the users start transitioning through screens, you will find that content targeted to those screens doesn't appear, content from the previous screen won't be removed and events targeting the second screen won't fire. From my investigations this appear to com about when the SPA updates or removes the DOM elements and FXM is not aware of the transition. So the question is how can we make FXM aware of the transition?
The first aspect is understanding how your SPA transitions. One of the key requirements however is that after the transition is complete that FXM will be able to understand the current state. This essentially means are there any page filter rules in Sitecore that can observe the current state.
The simplest of these to observe is a change in the URL, which if your SPA supports deep linking or the "back" button in the browser should be a part of the SPA.
Once you know how it transitions the next step is determine when it has transitioned, this is going to vary from SPA to SPA and you may need to work with the team developing the SPA to get some help. There are some approaches that are more common then others however:
- There is often an even raised by the SPA when it transitions and with a bit of JavaScript debugging yo can probably discover it
- A lot of the SPA frameworks provide and even similar to the above
- Failing all else if the URL has change the location in the address bar has changed as well, so you can always poll it for changes
$( "#fxmScriptId" ).remove() $('body').append('<script id="fxmScriptId" src="//your-site/bundle/beacon" />' )
Please keep in mind the method that you use to reintroduce the beacon script to the page, as you need it to evaluate the JavaScript and some approaches won't do this.
If you have the above running you should see your tracking and content being served, but what you are probably also seeing is that the content from previous screens are not being removed. This is happening because we are just removing and re-adding the FXM beacon to the page and no one is doing a clean up.
To get around this I recommend encapsulating all of your FXM content in a class that you can target during a transition. Once you have a way of targeting that content you can then remove during the transitions, similar to the below. One thing to keep in mind however is that this is best suited to the "insert after" and "insert before" approaches to injecting content, as opposed to the "replace" approach as it will not allows you to restore the content that has been replaced.
$( "#fxmScriptId" ).remove() $( ".fxm-content" ).remove() $('body').append('<script id="fxmScriptId" src="//your-site/bundle/beacon" />' )
Now that we have all of the following wired up, when you transitions states through your SPA you should have both tracking and content matching the state of your SPA.