Examples

Framework-specific examples for integrating the FitSignal Widget SDK.

Vanilla JavaScript

Basic HTML/JavaScript integration using the CDN script.

<!DOCTYPE html>
<html>
<head>
  <title>My App</title>
</head>
<body>
  <!-- Your app content -->

  <!-- Load FitSignal SDK -->
  <script src="https://www.fitsignal.com/sdk/fitsignal.umd.js"></script>
  <script>
    // Initialize SDK
    FitSignal.init({
      apiKey: 'fs_live_your_api_key',
      debug: true
    });

    // Subscribe to events
    FitSignal.on('complete', function(data) {
      console.log('Survey completed:', data.surveyId);
    });

    // Identify user when they log in
    function onUserLogin(user) {
      FitSignal.identify({
        email: user.email,
        name: user.name,
        externalId: user.id
      });
    }

    // Reset when they log out
    function onUserLogout() {
      FitSignal.reset();
    }
  </script>
</body>
</html>

React

Create a provider component to handle initialization and user identification.

1. Create a FitSignal Provider

// components/FitSignalProvider.tsx
'use client';

import { useEffect } from 'react';
import { FitSignal } from '@fitsignal/widget-sdk';

interface User {
  id: string;
  email: string;
  name?: string;
}

interface FitSignalProviderProps {
  children: React.ReactNode;
  user: User | null;
}

export function FitSignalProvider({ children, user }: FitSignalProviderProps) {
  // Initialize SDK once
  useEffect(() => {
    FitSignal.init({
      apiKey: process.env.NEXT_PUBLIC_FITSIGNAL_API_KEY!,
      debug: process.env.NODE_ENV === 'development'
    });

    // Subscribe to events
    FitSignal.on('complete', (data) => {
      console.log('Survey completed:', data);
      // Track in analytics, etc.
    });

    return () => {
      FitSignal.off('complete');
    };
  }, []);

  // Identify user when they sign in
  useEffect(() => {
    if (user) {
      FitSignal.identify({
        email: user.email,
        name: user.name,
        externalId: user.id
      });
    } else {
      FitSignal.reset();
    }
  }, [user]);

  return <>{children}</>;
}

2. Use in your layout

// app/layout.tsx
import { FitSignalProvider } from '@/components/FitSignalProvider';
import { getUser } from '@/lib/auth';

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const user = await getUser();

  return (
    <html>
      <body>
        <FitSignalProvider user={user}>
          {children}
        </FitSignalProvider>
      </body>
    </html>
  );
}

Next.js

Use the Next.js Script component for optimal loading, or the npm package for full TypeScript support.

Option 1: Using Script component

// app/layout.tsx
import Script from 'next/script';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html>
      <body>
        {children}

        {/* Load FitSignal SDK */}
        <Script
          src="https://www.fitsignal.com/sdk/fitsignal.umd.js"
          strategy="afterInteractive"
          onLoad={() => {
            window.FitSignal.init({
              apiKey: process.env.NEXT_PUBLIC_FITSIGNAL_API_KEY,
              debug: process.env.NODE_ENV === 'development'
            });
          }}
        />
      </body>
    </html>
  );
}

Identify users with Clerk (or other auth)

// components/UserIdentifier.tsx
'use client';

import { useEffect } from 'react';
import { useUser } from '@clerk/nextjs'; // or your auth provider

export function UserIdentifier() {
  const { user, isSignedIn } = useUser();

  useEffect(() => {
    // Wait for FitSignal to be loaded
    if (typeof window.FitSignal === 'undefined') return;

    if (isSignedIn && user) {
      window.FitSignal.identify({
        email: user.primaryEmailAddress?.emailAddress || '',
        name: user.fullName || undefined,
        externalId: user.id
      });
    }
  }, [isSignedIn, user]);

  return null;
}

Option 2: npm package

For full TypeScript support, use the React example above with the npm package. This gives you proper types and allows importing FitSignal directly.

Vue

Initialize in your root component's mounted hook.

Options API

<!-- App.vue -->
<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
import { FitSignal } from '@fitsignal/widget-sdk';

export default {
  name: 'App',

  mounted() {
    // Initialize SDK
    FitSignal.init({
      apiKey: import.meta.env.VITE_FITSIGNAL_API_KEY,
      debug: import.meta.env.DEV
    });

    // Subscribe to events
    FitSignal.on('complete', (data) => {
      console.log('Survey completed:', data);
    });
  },

  watch: {
    // Watch for auth state changes
    '$store.state.user'(newUser, oldUser) {
      if (newUser && !oldUser) {
        // User logged in
        FitSignal.identify({
          email: newUser.email,
          name: newUser.name,
          externalId: newUser.id
        });
      } else if (!newUser && oldUser) {
        // User logged out
        FitSignal.reset();
      }
    }
  }
};
</script>

Composition API (Vue 3)

// composables/useFitSignal.ts
import { onMounted, watch } from 'vue';
import { FitSignal } from '@fitsignal/widget-sdk';
import { useAuth } from './useAuth';

export function useFitSignal() {
  const { user, isAuthenticated } = useAuth();

  onMounted(() => {
    FitSignal.init({
      apiKey: import.meta.env.VITE_FITSIGNAL_API_KEY,
      debug: import.meta.env.DEV
    });
  });

  watch(
    () => user.value,
    (newUser, oldUser) => {
      if (newUser && isAuthenticated.value) {
        FitSignal.identify({
          email: newUser.email,
          name: newUser.name,
          externalId: newUser.id
        });
      } else if (!newUser && oldUser) {
        FitSignal.reset();
      }
    },
    { immediate: true }
  );

  return {
    show: (surveyId?: string) => FitSignal.show(surveyId),
    hide: () => FitSignal.hide(),
    isEligible: (surveyId?: string) => FitSignal.isEligible(surveyId)
  };
}

Manual Trigger

Show surveys programmatically, for example on a feedback button click.

// Trigger survey on button click
const feedbackButton = document.getElementById('feedback-btn');

feedbackButton.addEventListener('click', async () => {
  // Check if user is eligible first
  const eligible = await FitSignal.isEligible();

  if (eligible) {
    FitSignal.show();
  } else {
    alert('You have already completed this survey.');
  }
});

When to use manual trigger

  • Feedback buttons in your UI
  • After specific user actions (completing a purchase, etc.)
  • When you want full control over survey timing

Analytics Integration

Track FitSignal events in your analytics platform.

Segment Example

// Integration with Segment analytics
FitSignal.on('complete', (data) => {
  analytics.track('Survey Completed', {
    surveyId: data.surveyId,
    source: 'fitsignal_widget'
  });
});

FitSignal.on('dismiss', (data) => {
  analytics.track('Survey Dismissed', {
    surveyId: data.surveyId,
    source: 'fitsignal_widget'
  });
});

Other platforms

The same pattern works with any analytics tool: Mixpanel, Amplitude, Google Analytics, PostHog, etc. Just replace the analytics.track() calls with your platform's equivalent.