FullStory Install / Embed Tag or SDK | OpsBlu Docs

FullStory Install / Embed Tag or SDK

Deployment approaches for installing FullStory tracking code across web, mobile, and server environments.

Installation Methods Overview

FullStory offers several deployment options depending on your technology stack, team structure, and use case:

Method Best For Pros Cons
Direct Embed Most sites, best performance Fast loading, full control Requires code deployment for changes
Google Tag Manager Marketing-managed sites No code deploys, easy testing Slight overhead, GTM dependency
Segment Multi-tool analytics stack Centralized tracking, easy tool swapping Added abstraction, potential delay
npm Package Modern JavaScript apps Type safety, bundle optimization Requires build step
Mobile SDK iOS/Android apps Native session replay Platform-specific integration

Getting Your Tracking Code

  1. Log in to FullStory
  2. Go to Settings > FullStory Setup
  3. Click Install FullStory
  4. Copy the tracking code snippet
  5. Note your Org ID (you'll need this)

Standard Web Installation

Paste the FullStory snippet in the <head> section of every page:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Your Page Title</title>

    <!-- FullStory Tracking Code -->
    <script>
    window['_fs_host'] = 'fullstory.com';
    window['_fs_script'] = 'edge.fullstory.com/s/fs.js';
    window['_fs_org'] = 'YOUR_ORG_ID';
    window['_fs_namespace'] = 'FS';
    (function(m,n,e,t,l,o,g,y){
        if (e in m) {if(m.console && m.console.log) { m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].');} return;}
        g=m[e]=function(a,b,s){g.q?g.q.push([a,b,s]):g._api(a,b,s);};g.q=[];
        o=n.createElement(t);o.async=1;o.crossOrigin='anonymous';o.src='https://'+_fs_script;
        y=n.getElementsByTagName(t)[0];y.parentNode.insertBefore(o,y);
        g.identify=function(i,v,s){g(l,{uid:i},s);if(v)g(l,v,s)};g.setUserVars=function(v,s){g(l,v,s)};g.event=function(i,v,s){g('event',{n:i,p:v},s)};
        g.anonymize=function(){g.identify(!!0)};
        g.shutdown=function(){g("rec",!1)};g.restart=function(){g("rec",!0)};
        g.log = function(a,b){g("log",[a,b])};
        g.consent=function(a){g("consent",!arguments.length||a)};
        g.identifyAccount=function(i,v){o='account';v=v||{};v.acctId=i;g(o,v)};
        g.clearUserCookie=function(){};
        g.setVars=function(n, p){g('setVars',[n,p]);};
        g._w={};y='XMLHttpRequest';g._w[y]=m[y];y='fetch';g._w[y]=m[y];
        if(m[y])m[y]=function(){return g._w[y].apply(this,arguments)};
        g._v="1.3.0";
    })(window,document,window['_fs_namespace'],'script','user');
    </script>
    <!-- End FullStory Tracking Code -->

</head>
<body>
    <!-- Your content -->
</body>
</html>

Important: Replace YOUR_ORG_ID with your actual FullStory Org ID.

Verification

After installation, verify FullStory is working:

Method 1: Browser Console

console.log(typeof FS);  // Should return "function"
console.log(FS._v);      // Shows FullStory version

Method 2: Network Tab

  1. Open DevTools > Network tab
  2. Filter by fullstory
  3. Look for request to edge.fullstory.com/s/fs.js
  4. Status should be 200 OK

Method 3: FullStory Dashboard

  1. Go to Settings > FullStory Setup
  2. Status should show "Installed and Recording"
  3. Click "View Recent Sessions" to see captured sessions

Environment-Specific Installation

Use server-side logic to inject different Org IDs per environment:

PHP Example:

<?php
$fullstory_org = ($_SERVER['SERVER_NAME'] === 'www.example.com')
    ? 'PROD_ORG_ID'  // Production
    : 'DEV_ORG_ID';  // Development
?>

<script>
window['_fs_org'] = '<?php echo $fullstory_org; ?>';
// ... rest of FullStory snippet
</script>

Node.js/Express Example:

// In your route or middleware
const fullstoryOrg = process.env.NODE_ENV === 'production'
    ? process.env.FULLSTORY_ORG_PROD
    : process.env.FULLSTORY_ORG_DEV;

res.render('layout', { fullstoryOrg });
<!-- In your view template -->
<script>
window['_fs_org'] = '<%= fullstoryOrg %>';
// ... rest of FullStory snippet
</script>

Ruby on Rails Example:

# In application.html.erb
<script>
window['_fs_org'] = '<%= Rails.env.production? ? ENV['FULLSTORY_ORG_PROD'] : ENV['FULLSTORY_ORG_DEV'] %>';
// ... rest of FullStory snippet
</script>

GTM allows non-developers to manage FullStory without code deployments.

Prerequisites

  • Google Tag Manager container installed on your site
  • Admin access to GTM
  • FullStory Org ID

Setup Instructions

Step 1: Create FullStory Tag

  1. Log in to Google Tag Manager
  2. Go to Tags > New
  3. Click Tag Configuration
  4. Select Custom HTML
  5. Name the tag: FullStory Tracking

Step 2: Add FullStory Code

Paste your FullStory snippet:

<script>
window['_fs_host'] = 'fullstory.com';
window['_fs_script'] = 'edge.fullstory.com/s/fs.js';
window['_fs_org'] = '{{FullStory Org ID}}';
window['_fs_namespace'] = 'FS';
(function(m,n,e,t,l,o,g,y){
    if (e in m) {if(m.console && m.console.log) { m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].');} return;}
    g=m[e]=function(a,b,s){g.q?g.q.push([a,b,s]):g._api(a,b,s);};g.q=[];
    o=n.createElement(t);o.async=1;o.crossOrigin='anonymous';o.src='https://'+_fs_script;
    y=n.getElementsByTagName(t)[0];y.parentNode.insertBefore(o,y);
    g.identify=function(i,v,s){g(l,{uid:i},s);if(v)g(l,v,s)};g.setUserVars=function(v,s){g(l,v,s)};g.event=function(i,v,s){g('event',{n:i,p:v},s)};
    g.anonymize=function(){g.identify(!!0)};
    g.shutdown=function(){g("rec",!1)};g.restart=function(){g("rec",!0)};
    g.log = function(a,b){g("log",[a,b])};
    g.consent=function(a){g("consent",!arguments.length||a)};
    g.identifyAccount=function(i,v){o='account';v=v||{};v.acctId=i;g(o,v)};
    g.clearUserCookie=function(){};
    g.setVars=function(n, p){g('setVars',[n,p]);};
    g._w={};y='XMLHttpRequest';g._w[y]=m[y];y='fetch';g._w[y]=m[y];
    if(m[y])m[y]=function(){return g._w[y].apply(this,arguments)};
    g._v="1.3.0";
})(window,document,window['_fs_namespace'],'script','user');
</script>

Step 3: Create GTM Variable

For cleaner management, create a Constant variable:

  1. Go to Variables > New
  2. Name: FullStory Org ID
  3. Type: Constant
  4. Value: Your FullStory Org ID (e.g., o-1A2B3C-na1)

Step 4: Set Trigger

  1. Under Triggering, click to add a trigger
  2. Select All Pages (Page View trigger)
  3. Optionally, add exceptions for internal traffic or admin pages

Step 5: Test in Preview Mode

  1. Click Preview in GTM
  2. Enter your website URL
  3. Browse your site in the debug window
  4. In GTM Debug panel, verify FullStory Tracking tag fires
  5. Check console: console.log(typeof FS) should return "function"

Step 6: Publish

  1. Click Submit in GTM
  2. Add version name: "Added FullStory Tracking"
  3. Click Publish

Advanced GTM Configuration

Exclude Internal Traffic:

Create a trigger that excludes your office IP:

  1. Triggers > New
  2. Type: Page View
  3. Name: All Pages - External Only
  4. This trigger fires on: Some Page Views
  5. Add condition: Page Hostname does not contain localhost
  6. Or: {{Client IP}} does not equal 203.0.113.0 (your office IP)

Multi-Environment Setup with Lookup Table:

  1. Variables > New > Lookup Table
  2. Name: FullStory Org ID (Environment-Based)
  3. Input Variable: {{Page Hostname}}
  4. Map hostnames to Org IDs:
    • www.example.como-PROD-na1
    • staging.example.como-STAGING-na1
    • dev.example.como-DEV-na1
  5. Default Value: o-DEV-na1

Segment Integration

Segment is a customer data platform that centralizes data collection.

Setup

In Segment Dashboard:

  1. Go to Destinations > Add Destination
  2. Search for "FullStory"
  3. Click Configure FullStory
  4. Select source(s) to connect
  5. Enter your FullStory Org ID
  6. Enable the destination

In Your Code:

No FullStory-specific code needed. Segment handles everything:

// Identify user (syncs to FullStory)
analytics.identify('user_123', {
  email: 'user@example.com',
  plan: 'premium',
  signupDate: '2024-01-15'
});

// Track event (sent to FullStory)
analytics.track('Button Clicked', {
  button_name: 'Sign Up CTA',
  location: 'homepage'
});

// Page view (auto-tracked)
analytics.page('Homepage');

These automatically translate to FullStory:

// Becomes:
FS.identify('user_123', {
  email_str: 'user@example.com',
  plan_str: 'premium',
  signupDate_str: '2024-01-15'
});

FS.event('Button Clicked');
// Note: Event properties are not passed (FullStory limitation)

Limitations

  • Event properties from Segment are not forwarded to FullStory
  • User traits are synced, but events are name-only
  • Use descriptive event names to compensate

npm Package (Modern JavaScript Apps)

For apps using npm and build tools (Webpack, Vite, etc.):

Installation

npm install @fullstory/browser

Usage

Basic setup:

import FullStory from '@fullstory/browser';

FullStory.init({ orgId: 'YOUR_ORG_ID' });

With TypeScript:

import FullStory, { FullStoryAPI } from '@fullstory/browser';

FullStory.init({ orgId: 'YOUR_ORG_ID' });

// Type-safe API calls
FullStory.event('Button Clicked', {
  button_name: 'Sign Up',
  location: 'homepage'
});

FullStory.identify('user_123', {
  email_str: 'user@example.com',
  plan_str: 'premium'
});

Framework-Specific Integration

React:

// In App.js or index.js
import { useEffect } from 'react';
import FullStory from '@fullstory/browser';

function App() {
  useEffect(() => {
    FullStory.init({ orgId: process.env.REACT_APP_FULLSTORY_ORG });
  }, []);

  return (
    <div className="App">
      {/* Your app */}
    </div>
  );
}

export default App;

React Hook:

// hooks/useFullStory.js
import { useEffect } from 'react';
import FullStory from '@fullstory/browser';

export function useFullStory(user) {
  useEffect(() => {
    if (user) {
      FullStory.identify(user.id, {
        email_str: user.email,
        plan_str: user.plan
      });
    }
  }, [user]);

  const trackEvent = (name, properties) => {
    FullStory.event(name, properties);
  };

  return { trackEvent };
}

Vue.js:

// main.js
import { createApp } from 'vue';
import FullStory from '@fullstory/browser';
import App from './App.vue';

FullStory.init({ orgId: process.env.VUE_APP_FULLSTORY_ORG });

const app = createApp(App);
app.config.globalProperties.$FS = FullStory;
app.mount('#app');
// In components
export default {
  methods: {
    trackButtonClick() {
      this.$FS.event('Button Clicked', {
        location: 'settings_page'
      });
    }
  }
}

Next.js:

// pages/_app.js
import { useEffect } from 'react';
import FullStory from '@fullstory/browser';

function MyApp({ Component, pageProps }) {
  useEffect(() => {
    FullStory.init({ orgId: process.env.NEXT_PUBLIC_FULLSTORY_ORG });
  }, []);

  return <Component {...pageProps} />;
}

export default MyApp;

Angular:

// app.module.ts
import { APP_INITIALIZER, NgModule } from '@angular/core';
import FullStory from '@fullstory/browser';

export function initializeFullStory() {
  return () => {
    FullStory.init({ orgId: 'YOUR_ORG_ID' });
  };
}

@NgModule({
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initializeFullStory,
      multi: true
    }
  ]
})
export class AppModule { }

Mobile SDK Installation

iOS (Swift)

Step 1: Install via CocoaPods

# Podfile
pod 'FullStory', '~> 1.40'
pod install

Step 2: Initialize in AppDelegate

import UIKit
import FullStory

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        FullStory.startWithOrg("YOUR_ORG_ID")

        return true
    }
}

Step 3: Track Events

import FullStory

// Track event
FS.event("Button Clicked", properties: [
    "button_name": "Sign Up",
    "screen": "onboarding"
])

// Identify user
FS.identify("user_123", userVars: [
    "email": "user@example.com",
    "plan": "premium"
])

Android (Kotlin)

Step 1: Add Dependency

// app/build.gradle
dependencies {
    implementation 'com.fullstory:instrumentation-full:1.40.0'
}

Step 2: Initialize in Application Class

import android.app.Application
import com.fullstory.FS

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        FS.start("YOUR_ORG_ID")
    }
}

Step 3: Track Events

import com.fullstory.FS

// Track event
FS.event("Button Clicked", mapOf(
    "button_name" to "Sign Up",
    "screen" to "onboarding"
))

// Identify user
FS.identify("user_123", mapOf(
    "email" to "user@example.com",
    "plan" to "premium"
))

Content Security Policy (CSP) Configuration

If your site uses CSP headers, you must whitelist FullStory domains:

Content-Security-Policy:
    script-src 'self' https://edge.fullstory.com https://fullstory.com;
    connect-src 'self' https://rs.fullstory.com wss://rs.fullstory.com;
    img-src 'self' https://rs.fullstory.com data:;
    font-src 'self' https://edge.fullstory.com;
    style-src 'self' 'unsafe-inline';

Using Nonce-Based CSP

For stricter CSP:

<script nonce="random-nonce-value">
    // FullStory snippet here
</script>
Content-Security-Policy: script-src 'nonce-random-nonce-value'

Validation & Testing

Post-Installation Checklist

  • FullStory script loads without errors
  • FS function is available in console
  • Dashboard shows "Installed and Recording"
  • Sessions are being captured
  • No console errors related to FullStory
  • Page load performance is acceptable
  • Works across major browsers
  • Works on mobile devices
  • CSP allows FullStory (if applicable)

Browser Testing

Test in multiple browsers:

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)
  • Mobile Safari (iOS)
  • Chrome Mobile (Android)

Performance Testing

Measure impact on page load:

const start = performance.now();

window.addEventListener('load', () => {
  const end = performance.now();
  console.log(`Page load time: ${end - start}ms`);
});

Target: FullStory should add less than 100ms to page load time.

Troubleshooting

Common Installation Issues

Issue Symptoms Possible Causes Solutions
FullStory not loading No sessions appear in dashboard, FS is undefined - Incorrect Org ID
- Script blocked by ad blocker
- Network/firewall blocking FullStory
- Script tag syntax error
- Verify Org ID in Settings > FullStory Setup
- Test with ad blocker disabled
- Check Network tab for failed requests
- Validate script syntax (check for typos)
Sessions not recording Script loads but no sessions in dashboard - FullStory not initialized
- Sampling rate set too low
- Recording paused/shut down
- Browser privacy settings
- Check FS.getCurrentSessionURL() in console
- Review sampling settings in dashboard
- Call FS.restart() to resume recording
- Test in incognito/private browsing mode
CSP blocking script Console error: "Refused to load script" - Content Security Policy blocking FullStory domains
- Missing CSP directives
- Add FullStory domains to CSP header
- Include script-src, connect-src, img-src directives
- Test with CSP temporarily disabled
GTM tag not firing FullStory tag doesn't fire in Preview mode - Trigger not configured correctly
- Tag has exceptions/filters
- GTM container not published
- Tag order/priority issues
- Verify trigger set to "All Pages"
- Check tag firing conditions
- Publish GTM container
- Ensure FullStory tag fires early (higher priority)
Wrong environment tracking Dev sessions appearing in production dashboard - Using production Org ID in all environments
- Environment detection logic failing
- Use environment-specific Org IDs
- Verify process.env or server-side logic
- Check hostname detection code
Console errors JavaScript errors mentioning FullStory - Namespace conflict with existing code
- Invalid configuration options
- Incorrect API usage
- Change _fs_namespace to avoid conflicts
- Review FullStory config object
- Check FullStory API documentation
Mobile SDK not tracking iOS/Android app not recording sessions - Incorrect Org ID in SDK initialization
- SDK not initialized in app lifecycle
- Network permissions missing
- Verify Org ID matches dashboard
- Initialize in application:didFinishLaunching (iOS) or onCreate (Android)
- Check app network permissions
npm package issues Import errors or build failures - Package not installed
- Version incompatibility
- TypeScript configuration issues
- Run npm install @fullstory/browser
- Check package version compatibility
- Update tsconfig.json if using TypeScript
Segment integration not working Events/identify calls not reaching FullStory - FullStory destination not enabled
- Incorrect Org ID in Segment settings
- Destination mappings incorrect
- Enable FullStory in Segment destinations
- Verify Org ID in Segment dashboard
- Check Segment debugger for errors
Cross-origin iframe issues Parent or iframe not recording - Different origins (CSP restrictions)
- FullStory not installed on both
- Browser security policies
- Install FullStory on both parent and iframe
- Use same Org ID for both
- Cross-origin iframes cannot be fully recorded (browser limitation)

Debug Commands

Use these console commands to diagnose issues:

// Check if FullStory is loaded
typeof FS;  // Should return "function"

// Get current FullStory version
FS._v;

// Get current session URL
FS.getCurrentSessionURL();

// Check if recording is active
FS.isRecording;  // May not be available in all versions

// Manually restart recording
FS.restart();

// Shutdown recording
FS.shutdown();

// Check FullStory configuration
window._fs_org;  // Your Org ID
window._fs_namespace;  // Namespace (default: "FS")

Network Debugging

Check script loading:

  1. Open DevTools > Network tab
  2. Filter by fullstory
  3. Look for request to edge.fullstory.com/s/fs.js
  4. Status should be 200 OK
  5. Check response size (should be ~100-200KB)

Check data transmission:

  1. Filter Network by rs.fullstory.com
  2. Trigger some interactions on your site
  3. Look for POST requests to /rec/
  4. Inspect request payload (contains session data)

Installation Validation Checklist

Use this checklist after installation:

Basic Setup:

  • FullStory script added to <head> section
  • Correct Org ID used (matches dashboard)
  • Script loads without errors (check Console)
  • FS function available globally (typeof FS === 'function')
  • Dashboard shows "Installed and Recording" status

Session Recording:

  • New sessions appear in dashboard within 2-3 minutes
  • FS.getCurrentSessionURL() returns valid session URL
  • Session replay shows your interactions
  • Mouse movements and clicks captured
  • Page transitions recorded (for SPAs)

Performance:

  • Page load time impact < 100ms
  • No visible delay in page rendering
  • No console errors or warnings
  • Script loads asynchronously (non-blocking)

Cross-Browser:

  • Works in Chrome
  • Works in Firefox
  • Works in Safari
  • Works in Edge
  • Works on Mobile Safari (iOS)
  • Works on Chrome Mobile (Android)

Privacy & Security:

  • CSP allows FullStory domains (if applicable)
  • Sensitive data masked/excluded
  • Cookie consent integrated (if required)
  • Privacy policy updated

Environment-Specific Troubleshooting

Development Environment:

  • Use separate Org ID for dev
  • Enable 100% session recording (no sampling)
  • Use FullStory dev dashboard for testing
  • Disable production integrations (Slack, etc.)

Staging Environment:

  • Mirror production Org ID (or use staging Org)
  • Test with realistic user scenarios
  • Verify all features work end-to-end
  • Check integrations function correctly

Production Environment:

  • Monitor quota usage regularly
  • Set appropriate sampling rate if needed
  • Enable error monitoring/alerts
  • Document production Org ID securely

Getting Help

If issues persist after troubleshooting:

  1. Check FullStory Status Page: status.fullstory.com
  2. Review Help Center: help.fullstory.com
  3. Contact Support: Include:
    • Your Org ID
    • Browser and version
    • Console errors (screenshot)
    • Network tab screenshots
    • Steps to reproduce the issue
    • Expected vs actual behavior

Next Steps:

Additional Resources: