> ## Documentation Index
> Fetch the complete documentation index at: https://docs.userboo.st/llms.txt
> Use this file to discover all available pages before exploring further.

# Web Apps

> Universal UserBoost integration for React, Next.js, Vue, Angular, and any JavaScript web application

## When to Use Web Apps Integration

**Perfect for web applications:**

* React, Vue, Angular, Svelte applications
* Next.js, Nuxt.js, SvelteKit applications
* Static websites with JavaScript
* Progressive Web Apps (PWAs)
* Any frontend running in a browser

**Key benefits:**

* ✅ Real-time user interaction tracking
* ✅ Automatic page view and navigation tracking
* ✅ Easy integration with any framework
* ✅ Works with existing code - no major changes
* ✅ Client-side event queueing and retry logic

***

## Quick Setup (5 minutes)

<Steps>
  <Step title="Get your API key">
    1. Sign up at [userboo.st](https://userboo.st)
    2. Go to **Settings** → **API Keys**
    3. Copy your **Client-side API key** (starts with `ub_live_`)

    <Note>
      Use the **client-side** API key for web apps, not the server-side key.
    </Note>
  </Step>

  <Step title="Choose your installation method">
    Pick the approach that fits your application:

    <Tabs>
      <Tab title="NPM Package">
        **Recommended for modern frameworks**

        ```bash theme={null}
        npm install @userboost/sdk
        # OR
        yarn add @userboost/sdk
        ```

        ```javascript theme={null}
        import { UserBoost } from '@userboost/sdk';

        UserBoost.init({
          apiKey: 'ub_live_your_client_key_here',
          debug: process.env.NODE_ENV === 'development',
        });
        ```
      </Tab>

      <Tab title="Script Tag">
        **Perfect for static sites or quick testing**

        ```html theme={null}
        <script src="https://cdn.userboo.st/js/latest/userboost.min.js"></script>
        <script>
          ub.init({
            apiKey: 'ub_live_your_client_key_here',
            debug: true, // Enable for development
          });
        </script>
        ```
      </Tab>

      <Tab title="Async Loader">
        **Best performance for production**

        ```html theme={null}
        <script>
          (function(w,d,s,g,u){
            if(w[g]&&w[g].initialized)return;
            var ub={q:[],initialized:false,loaded:false};
            ["init","event","identify","flush"].forEach(m=>{
              ub[m]=function(){ub.q.push([m,arguments])};
            });
            w[g]=ub;
            var sc=d.createElement(s),fs=d.getElementsByTagName(s)[0];
            sc.async=true;sc.src=u;
            fs&&fs.parentNode&&fs.parentNode.insertBefore(sc,fs);
            ub.initialized=true;
          })(window,document,"script","ub","https://cdn.userboo.st/js/latest/userboost.min.js");

          ub.init({ apiKey: 'ub_live_your_client_key_here' });
        </script>
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Track your first event">
    The API is identical across all installation methods:

    ```javascript theme={null}
    // Track page views
    ub.event('page_viewed', {
      user: {
        id: 'user_123',
        email: 'john@example.com'
      },
      properties: {
        page: '/dashboard',
        referrer: document.referrer
      }
    });

    // Track button clicks
    ub.event('button_clicked', {
      user: { id: 'user_123' },
      properties: {
        button_text: 'Get Started',
        location: 'hero_section'
      }
    });
    ```
  </Step>

  <Step title="Verify it's working">
    1. Go to your [UserBoost dashboard](https://userboo.st/dashboard)
    2. Navigate to **Events** → **Live Stream**
    3. Interact with your web app
    4. Events should appear in the dashboard within 30 seconds

    <Note>
      Enable debug mode during development to see events in your browser console.
    </Note>
  </Step>
</Steps>

***

## Framework Integration Patterns

UserBoost uses the same API everywhere. Here's how to integrate it with popular frameworks:

<Tabs>
  <Tab title="React">
    ```jsx theme={null}
    // App.js
    import React, { useEffect } from 'react';
    import { UserBoost } from '@userboost/sdk';

    function App() {
      useEffect(() => {
        UserBoost.init({
          apiKey: process.env.REACT_APP_USERBOOST_API_KEY,
          debug: process.env.NODE_ENV === 'development'
        });

        // Track app load
        UserBoost.event('app_loaded', {
          user: { id: getCurrentUserId() },
          properties: { page: 'home' }
        });
      }, []);

      return <div>{/* Your app */}</div>;
    }

    // Components can track events anywhere
    function SignupButton() {
      const handleClick = () => {
        UserBoost.event('signup_button_clicked', {
          user: { id: getCurrentUserId() },
          properties: { location: 'header' }
        });
      };

      return <button onClick={handleClick}>Sign Up</button>;
    }
    ```
  </Tab>

  <Tab title="Next.js">
    ```javascript theme={null}
    // pages/_app.js
    import { UserBoost } from '@userboost/sdk';
    import { useEffect } from 'react';
    import { useRouter } from 'next/router';

    function MyApp({ Component, pageProps }) {
      const router = useRouter();

      useEffect(() => {
        UserBoost.init({
          apiKey: process.env.NEXT_PUBLIC_USERBOOST_API_KEY,
          debug: process.env.NODE_ENV === 'development'
        });
      }, []);

      useEffect(() => {
        const handleRouteChange = (url) => {
          UserBoost.event('page_viewed', {
            user: { id: getCurrentUserId() },
            properties: { page: url }
          });
        };

        router.events.on('routeChangeComplete', handleRouteChange);
        return () => router.events.off('routeChangeComplete', handleRouteChange);
      }, [router.events]);

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

  <Tab title="Vue.js">
    ```javascript theme={null}
    // main.js
    import { createApp } from 'vue';
    import { UserBoost } from '@userboost/sdk';
    import App from './App.vue';

    UserBoost.init({
      apiKey: import.meta.env.VITE_USERBOOST_API_KEY,
      debug: import.meta.env.DEV
    });

    const app = createApp(App);

    // Make UserBoost available globally
    app.config.globalProperties.$ub = UserBoost;

    app.mount('#app');
    ```

    ```vue theme={null}
    <!-- Component.vue -->
    <template>
      <button @click="trackClick">Track Event</button>
    </template>

    <script>
    export default {
      methods: {
        trackClick() {
          this.$ub.event('button_clicked', {
            user: { id: this.getCurrentUserId() },
            properties: { component: 'hero-section' }
          });
        }
      }
    }
    </script>
    ```
  </Tab>

  <Tab title="Angular">
    ```typescript theme={null}
    // app.component.ts
    import { Component, OnInit } from '@angular/core';
    import { UserBoost } from '@userboost/sdk';
    import { environment } from '../environments/environment';

    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html'
    })
    export class AppComponent implements OnInit {
      ngOnInit() {
        UserBoost.init({
          apiKey: environment.userboostApiKey,
          debug: !environment.production
        });

        UserBoost.event('app_loaded', {
          user: { id: this.getCurrentUserId() },
          properties: { framework: 'angular' }
        });
      }

      trackButtonClick() {
        UserBoost.event('button_clicked', {
          user: { id: this.getCurrentUserId() },
          properties: { action: 'signup' }
        });
      }
    }
    ```
  </Tab>

  <Tab title="Vanilla JS">
    ```html theme={null}
    <!DOCTYPE html>
    <html>
    <head>
      <script src="https://cdn.userboo.st/js/latest/userboost.min.js"></script>
    </head>
    <body>
      <button id="signup-btn">Sign Up</button>

      <script>
        // Initialize UserBoost
        ub.init({
          apiKey: 'ub_live_your_client_key_here',
          debug: true
        });

        // Track page load
        ub.event('page_loaded', {
          user: { id: 'anonymous_user' },
          properties: {
            page: window.location.pathname,
            timestamp: new Date().toISOString()
          }
        });

        // Track button clicks
        document.getElementById('signup-btn').addEventListener('click', function() {
          ub.event('signup_clicked', {
            user: { id: getCurrentUserId() },
            properties: { source: 'landing_page' }
          });
        });
      </script>
    </body>
    </html>
    ```
  </Tab>
</Tabs>

***

## Common Web Event Patterns

### Page Views and Navigation

```javascript theme={null}
// Manual page view tracking
ub.event('page_viewed', {
  user: { id: getCurrentUserId() },
  properties: {
    page: window.location.pathname,
    title: document.title,
    referrer: document.referrer,
    timestamp: new Date().toISOString()
  }
});

// Single Page App navigation
function trackPageView(route) {
  ub.event('page_viewed', {
    user: { id: getCurrentUserId() },
    properties: {
      page: route,
      previous_page: getPreviousRoute(),
      navigation_type: 'spa'
    }
  });
}
```

### User Interactions

```javascript theme={null}
// Button clicks
document.querySelectorAll('button[data-track]').forEach(button => {
  button.addEventListener('click', () => {
    ub.event('button_clicked', {
      user: { id: getCurrentUserId() },
      properties: {
        button_text: button.textContent,
        button_id: button.id,
        location: button.dataset.track
      }
    });
  });
});

// Form submissions
function trackFormSubmission(formName, formData) {
  ub.event('form_submitted', {
    user: { id: getCurrentUserId() },
    properties: {
      form_name: formName,
      fields_completed: Object.keys(formData).length,
      form_url: window.location.pathname
    }
  });
}
```

### User Onboarding Events

```javascript theme={null}
// User registration
ub.event('user_signed_up', {
  user: {
    id: newUser.id,
    email: newUser.email,
    traits: {
      signup_method: 'email',
      plan: 'free'
    }
  },
  properties: {
    referral_source: document.referrer,
    signup_page: window.location.pathname
  }
});

// Profile completion steps
ub.event('profile_step_completed', {
  user: { id: userId },
  properties: {
    step: 'basic_info',
    completion_percentage: 25,
    time_spent: calculateTimeSpent()
  }
});

// First key action
ub.event('first_project_created', {
  user: { id: userId },
  properties: {
    project_type: 'website',
    days_since_signup: getDaysSinceSignup(),
    onboarding_completed: true
  }
});
```

***

## Advanced Features

### User Identification

```javascript theme={null}
// Identify users when they log in
ub.identify({
  id: 'user_123',
  email: 'john@example.com',
  name: 'John Doe',
  traits: {
    plan: 'pro',
    signup_date: '2024-01-15',
    company: 'Acme Corp'
  }
});

// Update user traits
ub.identify({
  id: 'user_123',
  traits: {
    plan: 'enterprise', // Updated plan
    last_login: new Date().toISOString()
  }
});
```

### Event Batching and Performance

```javascript theme={null}
// Events are automatically batched, but you can control it
ub.init({
  apiKey: 'your_key',
  batchSize: 10,        // Send events in batches of 10
  flushInterval: 5000,  // Auto-flush every 5 seconds
  maxRetries: 3         // Retry failed requests 3 times
});

// Manual queue management
ub.flush();                    // Send all queued events immediately
console.log(ub.getQueueLength()); // Check how many events are queued
```

### Environment Configuration

```javascript theme={null}
// Development vs Production
const config = {
  development: {
    apiKey: 'ub_live_dev_key_here',
    debug: true,
    flushInterval: 1000  // Flush more frequently in dev
  },
  production: {
    apiKey: 'ub_live_prod_key_here',
    debug: false,
    flushInterval: 10000
  }
};

ub.init(config[process.env.NODE_ENV] || config.development);
```

***

## Environment Variables

Set up your API keys securely:

<CodeGroup>
  ```bash .env.local (Next.js) theme={null}
  NEXT_PUBLIC_USERBOOST_API_KEY=ub_live_your_client_key_here
  ```

  ```bash .env (React/Vite) theme={null}
  REACT_APP_USERBOOST_API_KEY=ub_live_your_client_key_here
  VITE_USERBOOST_API_KEY=ub_live_your_client_key_here
  ```

  ```bash .env (Angular) theme={null}
  USERBOOST_API_KEY=ub_live_your_client_key_here
  ```
</CodeGroup>

<Warning>
  **Client-side API keys are safe to expose** in frontend code, but make sure you're using the correct client-side key (not server-side).
</Warning>

***

## Testing & Debugging

### Debug Mode

```javascript theme={null}
// Enable detailed console logging
ub.init({
  apiKey: 'your_key',
  debug: true
});

// Or enable debug mode after initialization
ub.setDebug(true);
```

### Test Events

```javascript theme={null}
// Send a test event to verify integration
ub.event('web_integration_test', {
  user: { id: `test_user_${Date.now()}` },
  properties: {
    test: true,
    browser: navigator.userAgent,
    timestamp: new Date().toISOString(),
    url: window.location.href
  }
});
```

### Browser DevTools

With debug mode enabled, you'll see detailed logs in the browser console:

```
[UserBoost] Initializing with key: ub_live_***
[UserBoost] Tracking event: page_viewed
[UserBoost] Event queued. Queue length: 1
[UserBoost] Auto-flushing due to time window
[UserBoost] Sending 1 events to API
[UserBoost] Events sent successfully
```

***

## Common Issues

<AccordionGroup>
  <Accordion title="Events not appearing in dashboard" icon="exclamation-triangle">
    **Check these common causes:**

    * Using server-side API key instead of client-side key
    * Missing required `user.id` field in events
    * Ad blockers blocking the UserBoost domain
    * Network connectivity issues
    * Browser extensions interfering with requests

    **Enable debug mode to see detailed error messages in console.**
  </Accordion>

  <Accordion title="Script not loading" icon="globe">
    **For CDN integration:**

    * Check if CDN is accessible from your domain
    * Verify script URL is correct
    * Check browser network tab for loading errors
    * Try the async loader for better reliability

    **For NPM integration:**

    * Ensure package is installed: `npm list @userboost/sdk`
    * Check import statements are correct
    * Verify build process includes the package
  </Accordion>

  <Accordion title="TypeScript errors" icon="code">
    **Type definitions are included automatically:**

    ```typescript theme={null}
    import { UserBoost, UserData, EventData } from '@userboost/sdk';

    const userData: UserData = {
      id: 'user_123',
      email: 'john@example.com'
    };

    const eventData: EventData = {
      user: userData,
      properties: { action: 'signup' }
    };

    UserBoost.event('user_action', eventData);
    ```
  </Accordion>

  <Accordion title="Content Security Policy (CSP) issues" icon="shield">
    **Add UserBoost domains to your CSP:**

    ```html theme={null}
    <meta http-equiv="Content-Security-Policy"
          content="connect-src 'self' https://api.userboo.st;
                   script-src 'self' https://cdn.userboo.st;">
    ```
  </Accordion>
</AccordionGroup>

***

## Performance Optimization

### Lazy Loading

```javascript theme={null}
// Load UserBoost only when needed
async function initUserBoost() {
  const { UserBoost } = await import('@userboost/sdk');

  UserBoost.init({
    apiKey: 'your_key',
    debug: false
  });

  return UserBoost;
}

// Use when user performs their first action
document.addEventListener('click', async () => {
  const ub = await initUserBoost();
  ub.event('first_interaction', {
    user: { id: getCurrentUserId() }
  });
}, { once: true });
```

### Bundle Size Optimization

The UserBoost SDK is optimized for minimal bundle impact:

* **ESM build**: \~22KB minified
* **Gzipped**: \~8KB
* **Tree-shakeable**: Only import what you use

***

## What's Next?

<CardGroup cols={2}>
  <Card title="Track Events" icon="activity" href="/tracking/events">
    Learn advanced event tracking patterns and user journey mapping.
  </Card>

  <Card title="User Identification" icon="user" href="/tracking/users">
    Set up user identification and trait management.
  </Card>
</CardGroup>

Your web application is now tracking user interactions! UserBoost will automatically build user journey funnels and help you identify where users get stuck in your onboarding flow.
