Configure Capture
FS('init') is the code-first way to configure capture settings that were historically set via window._fs_* globals. It is the recommended approach for new integrations, and existing sites can migrate their globals to init incrementally.
To get the full benefit of dropping globals, use snippet 2.1 or later. The modern snippet calls FS('init') automatically during bootstrap with your organization ID, host, and script path.
FS('init', {
env: { /* capture settings */ },
privacy: { /* optional privacy rules */ },
})
Snippet 2.1 and automatic initialization
When you install the Fullstory Snippet (version 2.1+), the snippet calls init under the hood:
FS('init', {
env: {
orgId: '<your org id>',
host: '<your host>',
script: '<edge script path>',
},
});
For standard snippet installs, you don't need to call init manually unless you want to override defaults. For code-first or bundler-based installs, call init yourself before capture starts, supplying at minimum orgId and either host or explicit host overrides (recHost, recSettingsHost, appHost, script).
Timing
FS('init') must be called before capture starts. It is recommended to call FS('init') immediately following the Fullstory snippet, as calls made after capture has begun are rejected.
- Calls queued before the FS script loads are processed during startup (the same queue used by other API calls).
- If you manually delay capture,
initmust still be called beforeFS('start').
Asynchronous Method
The asynchronous version, FS('initAsync'), resolves or rejects like other async API calls. It is rejected if called after capture has already started.
Environment configuration
The env object passed to FS('init') holds your capture settings: your organization ID, the hosts and script path Fullstory loads from, and behavior flags such as whether to start capturing on startup. Set only the keys you need to change — anything you omit falls back to its default.
Common env keys
- orgId string required
Organization ID. Required for capture to start. With snippet 2.1+,
orgId(along withhostandscript) is already set by the snippet's automaticinitcall and does not need to be repeated. Pass it manually only for code-first or bundler-based installs that skip the snippet. - host string optional
Base host. When set, Fullstory can derive
appHost,recHost,recSettingsHost, and the defaultscriptpath if those are not provided explicitly. For example,host: 'fullstory.com'yields recorder hostrs.fullstory.com, settings hostedge.fullstory.com, and app hostapp.fullstory.com. - script string optional
Path or URL to the FS script (
fs.js). - scheme string optional
Possible values:
http:,https:Protocol used for recorder and settings requests. Defaults to
https:. - captureOnStartup boolean optional
Whether to start capture immediately. Defaults to
true. Set tofalseto manually delay capture. - cookieDomain string optional
Cookie domain override.
- recHost string optional
Recorder host override.
- recSettingsHost string optional
Settings/CDN host override.
- appHost string optional
App host override.
- tabId string optional
Tab identifier.
Capture is disabled if orgId is missing or invalid, or if the required hosts and script cannot be resolved from your configuration.
Migrating from legacy globals
Earlier snippets configured capture by setting window._fs_* globals on the page. Snippet 2.1 replaces those globals with env keys on FS('init'), but it still reads any legacy globals it finds, so existing installs keep working while you migrate.
Legacy global variables are transformed into env keys through the following method:
- The
_fs_prefix is dropped. snake_caseis converted tocamelCase.- The resulting value is passed under
env.
| Legacy global | env key |
|---|---|
window._fs_org | orgId |
window._fs_host | host |
window._fs_script | script |
window._fs_capture_on_startup | captureOnStartup |
window._fs_cookie_domain | cookieDomain |
window._fs_rec_host | recHost |
window._fs_rec_settings_host | recSettingsHost |
window._fs_app_host | appHost |
Other globals follow the same naming pattern.
At fs.js startup, any remaining window._fs_* globals are snapshotted once as a base, then the env values from init are overlaid on top, so init always wins over a global regardless of call order. Once you have set the equivalent env keys, remove the matching globals to avoid confusion.
Get effective configuration
After capture settings are resolved, FS('getConfig') returns the effective configuration as { env: { ... } }. Use it to confirm settings after migrating from globals.
Timing
Unlike init, calls to getConfig are not auto-queued while fs.js is still loading. Calling the synchronous FS('getConfig') immediately after the snippet returns (before fs.js has loaded) returns null and silently discards the real result once it becomes available. Use the asynchronous version, FS('getConfigAsync'), to reliably wait for the effective configuration instead.
getConfig and getConfigAsync always resolve, even if capture has not initialized yet; in that case they resolve with null. They never reject, so check the result for null rather than using .catch().
Custom namespace
By default, the Fullstory API is exposed on the global window.FS, and the fs.js recorder binds to that same name. If FS collides with another global on your page, you can tell Fullstory to use a different name.
Unlike your other capture settings, the namespace is set directly in the snippet rather than through FS('init'). It's the name of the global your code calls, so snippet 2.1 establishes it up front and keeps it in sync across the two places that rely on it: the global the API binds to, and the data-fs-namespace attribute it writes on the injected fs.js <script> tag.
Set a custom namespace
In snippet 2.1, set the namespace by editing the 5th value passed to the function call at the bottom of the snippet—it comes right after the host and script and just before your org ID. Change 'FS' to the name you want; that one value both binds the global and is written to data-fs-namespace for you. You never edit data-fs-namespace directly.
Here's an example of replacing the default 'FS' namespace parameter with 'FullstoryAPI':
// ...bottom of the snippet. The 5th value is the namespace.
}(window, document, 'fullstory.com', 'edge.fullstory.com/s/fs.js', 'FullstoryAPI', '<your org id>');
Earlier snippets set the namespace through the window._fs_namespace global. While fs.js still honors that global for existing installs, setting it is no longer recommended—use the argument.
<script>
// Legacy approach, no longer recommended for snippet 2.1
window['_fs_namespace'] = 'FullstoryAPI';
</script>
Get the current namespace
Code that calls Fullstory without owning the install shouldn't assume the global is FS, since the customer may have renamed it. Discover the namespace at runtime instead.
The source of truth in 2.1 is the data-fs-namespace attribute on the injected fs.js <script> tag. Read it, then look up that name on window. Only fall back to the legacy window._fs_namespace global if the attribute is missing (for example, on an older v1 or v2.0 install), and finally to the default FS.
function getFullstory() {
// Snippet 2.1 writes the namespace to the fs.js script tag.
const el = document.querySelector('script[data-fs-namespace]');
const namespace =
el?.getAttribute('data-fs-namespace') ||
window._fs_namespace || // legacy v1 / v2.0 installs
'FS'; // default
return window[namespace];
}
const FullstoryAPI = getFullstory();
FullstoryAPI?.('setProperties', {
type: 'user',
properties: { pricingTier: 'gold' },
});
Keep these in mind:
- The API is callable immediately. As soon as the snippet runs, it installs a queue on the global—before
fs.jsfinishes loading. Calls made through the discovered global are queued and replayed once the recorder is ready. - Load Fullstory first. If your code runs before the snippet, neither the attribute nor the global exists yet, so discovery falls through to the
FSdefault. - Use
querySelector, notdocument.currentScript.currentScriptpoints at your own script. Selectingscript[data-fs-namespace]finds thefs.jstag the snippet injected. (fs.jsreads its own namespace viadocument.currentScript, but that only works from insidefs.jsitself.)