Yes, Fullstory can work seamlessly with most iframes! Depending on your scenario, capturing iframe content may require some additional configuration. This article covers common implementation scenarios as well as several things to keep in mind when working with iframes.
Support for common iframe Implementation Scenarios
This table outlines support for common iframe implementation scenarios. In the following scenarios, “outer page” refers to the top-most HTML page, the one not running in an iframe, or window.top
. Read on for more detailed information about each scenario.
Implementation Scenario |
Example |
Support |
1) The outer page is running Fullstory and your iframe runs on the same domain. |
A single-domain site using iframes to organize various components. |
|
2) The outer page is running Fullstory and your iframe runs on a different domain or a different subdomain on the same domain. |
A mixed-domain site using iframes to organize various components or an iframe from subdomain.example.com that appears on example.com. |
|
3) The outer page is not running Fullstory and you want to capture a page that runs in an iframe. |
Your content is embedded into a third-party site that doesn’t use Fullstory. |
|
4) You want to capture a page that runs in an iframe, but the outer page is capturing data in a different Fullstory account. |
Your content is embedded into a third-party site, but that site also uses Fullstory. |
|
5) The outer page is running Fullstory, but you don’t have access to the iframed content source code. |
A third-party support widget embedded in your site. |
1) The outer page is running Fullstory and all your iframes run on the same domain.
For example, you run a single-domain site, and use iframes to organize various components.
What to do: You don't need to do anything special. Run Fullstory on the outer page, and everything should get captured. If you also have the Fullstory data capture snippet inside your iframes, that's ok too; the data capture script within the iframes will automatically defer to the outer page.
Note: If the same-origin (same domain) iframe is empty when fs.js is executed on the main page, Fullstory will not insert itself into that frame and it will not be captured.
2) The outer page is running Fullstory and you have iframes running on a different domain.
IMPORTANT SECURITY NOTE:
Before configuring window['_fs_run_in_iframe']
, you should understand the security implications and configure your Content Security Policy (CSP) HTTP headers accordingly- specifically the frame-ancestors
directive.
Failure to configure your CSP headers while using this setting can bypass iframe security protections that are included in modern browsers. If you're unsure what this means, please contact us for further information before proceeding.
This case applies when you have a mixed-domain site that uses iframes, but logically it's all part of a single application and you want everything captured together. (Note: Click here for a detailed explanation of what "cross-origin" means. For example, an iframe from subdomain.example.com that appears on example.com would be considered a mixed-domain site environment.)
What to do: To capture outer page content, put the standard Fullstory data capture snippet on the outer page. Additionally, to capture the iframed content, add this special flag to the Fullstory data capture snippet and install the modified snippet on the page that is hosted within the iframe:
window['_fs_run_in_iframe'] = true; // Whoa there! Proceed with caution. Before adding this new variable inside the iframe, beware of the security implications and be sure to configure your CSP headers accordingly. See the security note above for more information.
So the resulting iframe script should start with window['_fs_run_in_iframe']
= true;
as the first line of your standard Fullstory data capture snippet.
The _fs_run_in_iframe flag tells Fullstory that the iframe should capture itself and communicate with the outer page that is also running Fullstory, so they show up together in a single capture. Again, this is only necessary if the iframe is cross-origin with respect to the outer page.
Note: If you'd like to capture an iframe where the sandbox
property is set, you'll also have to add allow-same-origin
to the sandbox
property or Fullstory will not be able to capture the contents of the iframe.
3) The outer page does not run Fullstory and you want to capture a page that runs in an iframe.
For example, you provide content in an iframe, which is embedded into a third-party site that doesn't use Fullstory.
What to do: Inside of the iframe, include the usual Fullstory data capture snippet and add this special flag to the script:
window['_fs_is_outer_script'] = true;
So the resulting iframe script will look something like:
window['_fs_is_outer_script'] = true; // <-- here is the new variable to add, only inside the iframe
window['_fs_debug'] = false;
window['_fs_host'] = 'www.fullstory.com';
(etc...)
The _fs_is_outer_script flag tells Fullstory that the iframe is the "root" of the captured data, and should be its own session.
4) You want to capture a page that runs in an iframe into your Fullstory account, but the outer page is capturing data into a different Fullstory account.
For example, maybe you provide content in an iframe, and it's embedded into a third-party site which also happens to be using Fullstory, but they have their own Fullstory account that's different from yours.
What to do: Follow the instructions from part 3, using the _fs_is_outer_script flag inside the iframe. The outer page will capture itself into one Fullstory account, which will render the iframe as an empty box. The iframe will capture itself into a different Fullstory account, and all you'll see is the iframe itself, not the content around it. There is no way to see all the content together in this scenario.
Please note that the contents of an iframe cannot be masked by adding a class of .fs-mask
to the iframe. Either the elements on the page itself will need to be masked, or you will need to add an exclude rule to the iframe.
5) The outer page is running Fullstory, but you don't have access to the iframed content source code.
If you have content in an iframe for which you do not have access to the source code, you will not be able to capture the contents of that iframe. One example of this may be a third-party support widget embedded within your site. If you’re unable to add your Fullstory data capture snippet to the iframed page content, it is not possible to capture the iframe contents for session playback.
Working with iframes and Fullstory
There are a few ways that Fullstory behaves differently or perhaps unexpectedly when working with iframes.
Limited support for the Fullstory JavaScript API within iframes
The only Fullstory JavaScript API method that is supported within iframes is the FS.event API. Calls to other JS API methods within iframes will have undefined behavior.
Using Embedded iframes
If you're using Fullstory to capture pages with embedded iframes and are also using postMessage()
to communicate across frames, you may see some unexpected messages in your message event handler.
Fullstory must use the postMessageAPI to communicate capture data from frames up to the parent window, because these frames may be on different domains.
Unfortunately, this communication mechanism has a design flaw in that there's no formal way to designate scripts. Thus, multiple scripts communicating over this channel will receive each others' messages and must find a way to exclude those not intended for it.
If another script on the page doesn't explicitly test the messages it receives, it may show exceptions or other errors. The following is an example of such a case:
window.addEventListener('message', function(e) {
var msg = JSON.parse(e.data);
doSomethingWith(msg.someField);
}, false);
The above code will throw an exception when it attempts to access msg.someField
.
The exception is harmless but produces error messages on the Javascript console. The best approach is to guard against this case with a simple test, such as:
window.addEventListener('message', function(e) {
var msg;
// Also ensure JSON parsing doesn't fail, because e.data could be text.
try { msg = JSON.parse(e.data); } catch (e) { }
// Ensure that this message was actually intended for us.
if ('someField' in msg) {
doSomethingWith(msg.someField);
}
}, false);
Approaching message handlers in this way will ensure that they're resilient not just to unexpected messages from fs.js but any other scripts that use postMessage()
to communicate across frames.