Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.fanfare.io/llms.txt

Use this file to discover all available pages before exploring further.

Browser Compatibility

This guide covers browser support, known compatibility issues, and workarounds.

Supported Browsers

Desktop Browsers

BrowserMinimum VersionNotes
Chrome80+Recommended
Firefox75+Full support
Safari13.1+See Safari notes below
Edge80+Chromium-based

Mobile Browsers

BrowserMinimum VersionNotes
Chrome (Android)80+Recommended
Safari (iOS)13.4+See Safari notes below
Samsung Internet12+Full support
Firefox (Android)75+Full support

Not Supported

  • Internet Explorer (all versions)
  • Opera Mini
  • UC Browser
  • Older browser versions

Required Browser Features

The Fanfare SDK requires these browser features:
FeatureUsageFallback
Fetch APIAPI requestsPolyfill available
PromisesAsync operationsPolyfill available
ES2020+Modern JavaScriptTranspilation
Web StorageSession persistenceGraceful degradation
WebSocketReal-time updatesPolling fallback

Safari-Specific Issues

Intelligent Tracking Prevention (ITP)

Safari’s ITP can affect cookie and storage behavior. Symptoms:
  • Sessions not persisting
  • Unexpected logouts
  • Cross-site tracking issues
Solutions:
  1. Use first-party cookies
    // SDK automatically uses first-party storage when possible
    const client = new FanfareClient({
      publishableKey: "pk_live_...",
      storage: "localStorage", // or "cookie"
    });
    
  2. Prompt for storage access
    // Request storage access if needed
    if (document.hasStorageAccess) {
      const hasAccess = await document.hasStorageAccess();
      if (!hasAccess) {
        await document.requestStorageAccess();
      }
    }
    

Private Browsing Mode

In Safari private browsing, localStorage and sessionStorage may be unavailable. Detection and handling:
function isStorageAvailable(): boolean {
  try {
    const test = "__storage_test__";
    localStorage.setItem(test, test);
    localStorage.removeItem(test);
    return true;
  } catch {
    return false;
  }
}

if (!isStorageAvailable()) {
  // Use in-memory storage fallback
  showWarning("Some features may not work in private browsing mode");
}

WebSocket Limitations

Safari has stricter WebSocket handling. Symptoms:
  • Connection drops after backgrounding
  • Reconnection issues
Solution: The SDK handles this automatically, but you can configure behavior:
const client = new FanfareClient({
  publishableKey: "pk_live_...",
  realtime: {
    reconnectOnVisible: true, // Reconnect when tab becomes visible
    heartbeatInterval: 30000, // Keep connection alive
  },
});

Mobile-Specific Issues

Background Tab Throttling

Browsers throttle background tabs to save battery. Impact:
  • Timers may be delayed
  • Real-time updates may pause
  • Position updates may lag
Handling:
// Listen for visibility changes
document.addEventListener("visibilitychange", () => {
  if (document.visibilityState === "visible") {
    // Refresh state when returning to tab
    client.refresh();
  }
});

iOS Safari Touch Handling

iOS Safari has unique touch event handling. 300ms tap delay workaround:
<meta name="viewport" content="width=device-width, initial-scale=1" />
/* Prevent zoom on double-tap */
button {
  touch-action: manipulation;
}

Keyboard and Viewport

Mobile keyboard can cause layout issues. Solution:
/* Use visual viewport */
.fixed-bottom {
  position: fixed;
  bottom: env(safe-area-inset-bottom);
}
// Handle viewport changes
if (window.visualViewport) {
  window.visualViewport.addEventListener("resize", () => {
    document.documentElement.style.setProperty("--viewport-height", `${window.visualViewport.height}px`);
  });
}

Feature Detection

Use feature detection rather than browser detection.
function checkBrowserSupport(): { supported: boolean; issues: string[] } {
  const issues: string[] = [];

  // Check Fetch API
  if (!window.fetch) {
    issues.push("Fetch API not supported");
  }

  // Check Promises
  if (!window.Promise) {
    issues.push("Promises not supported");
  }

  // Check Web Storage
  try {
    localStorage.setItem("test", "test");
    localStorage.removeItem("test");
  } catch {
    issues.push("Local storage not available");
  }

  // Check WebSocket
  if (!window.WebSocket) {
    issues.push("WebSocket not supported");
  }

  return {
    supported: issues.length === 0,
    issues,
  };
}

// Usage
const { supported, issues } = checkBrowserSupport();
if (!supported) {
  showBrowserUpgradeMessage(issues);
}

Show Upgrade Message

function BrowserUpgradeMessage({ issues }: { issues: string[] }) {
  return (
    <div className="browser-upgrade">
      <h2>Please upgrade your browser</h2>
      <p>
        Your browser doesn't support some features needed for this experience. Please upgrade to a modern browser like
        Chrome, Firefox, or Safari.
      </p>
      <ul>
        {issues.map((issue) => (
          <li key={issue}>{issue}</li>
        ))}
      </ul>
    </div>
  );
}

Polyfills

Adding Polyfills

For older browsers, add polyfills:
// polyfills.ts
import "core-js/stable";
import "regenerator-runtime/runtime";

// Or use a polyfill service
// <script src="https://polyfill.io/v3/polyfill.min.js?features=fetch,Promise,Array.from"></script>

Conditional Loading

Load polyfills only when needed:
<script>
  if (!window.fetch) {
    document.write('<script src="/polyfills/fetch.js"><\/script>');
  }
</script>

Common Issues by Browser

Chrome

Issue: Extensions blocking requests Solution: Test in incognito mode or disable extensions
// Detect if request was blocked
fetch(url).catch((error) => {
  if (error.message.includes("blocked")) {
    showMessage("Browser extension may be blocking requests");
  }
});

Firefox

Issue: Enhanced Tracking Protection Solution: Ensure your domain is not on tracking lists Issue: Container tabs isolation Solution: Sessions may not share between containers by design

Safari

Issue: Aggressive caching Solution: Add cache-busting headers
fetch(url, {
  headers: {
    "Cache-Control": "no-cache",
  },
});

Edge (Legacy)

Issue: Not supported Solution: Redirect to modern Edge or Chrome
// Detect legacy Edge
const isLegacyEdge = navigator.userAgent.includes("Edge/");
if (isLegacyEdge) {
  showUpgradeMessage();
}

Testing Across Browsers

PriorityBrowsers
CriticalChrome (latest), Safari (latest), iOS Safari
HighFirefox (latest), Edge (latest), Chrome Android
MediumChrome (-1), Safari (-1), Samsung Internet

Testing Tools

  • BrowserStack: Cross-browser testing
  • Sauce Labs: Automated browser testing
  • Chrome DevTools: Device emulation
  • Safari Technology Preview: Test upcoming Safari features

Mobile Testing

// Detect mobile for testing
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);

// Or use media query
const isMobile = window.matchMedia("(max-width: 768px)").matches;

Performance Considerations

Browser-Specific Optimizations

// Safari: Prefer smaller bundle chunks
if (isSafari) {
  // Safari has stricter memory limits
}

// Mobile: Reduce animation complexity
if (isMobile) {
  // Use simpler animations
  document.documentElement.classList.add("reduced-motion");
}

Memory Management

// Clean up properly to avoid memory leaks
useEffect(() => {
  const subscription = client.subscribe(handler);

  return () => {
    subscription.unsubscribe();
  };
}, []);

Getting Help

If you encounter browser-specific issues:
  1. Check browser console for errors
  2. Test in incognito/private mode to rule out extensions
  3. Note exact browser version when reporting issues
  4. Provide reproduction steps if possible

Contact Support

Report browser-specific issues to our support team