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

# Session Tracking and Lifecycle in the Tappd Web SDK

> Learn how the Tappd Web SDK tracks browser sessions, configures timeouts, and handles SPAs with automatic session lifecycle management.

The Tappd Web SDK manages sessions automatically using a hybrid model that combines browser-based isolation with time-based expiration. You get complete session context attached to every event — no manual session handling required.

## How Sessions Work

The SDK uses two complementary mechanisms to define a session:

1. **Browser-based**: Each browser tab or window gets its own session, stored in memory.
2. **Time-based**: A session expires after a configurable period of inactivity (default: 30 minutes).

When both conditions are considered together, you get an accurate picture of a single user's focused engagement with your app.

### Session Lifecycle

<Steps>
  <Step title="Session Starts">
    A new session begins automatically when the SDK initializes on page load, when a user returns after a timeout, or when a user switches back to a tab after the session has expired.

    ```javascript theme={null}
    const tappd = new TappdSDK({
      appId: 'YOUR_APP_ID'
    });
    // A session ID is generated immediately: sess_abc123...
    ```
  </Step>

  <Step title="Activity Updates">
    The session's `lastActivityAt` timestamp is refreshed every time you call any tracking method — `track()`, `trackPageView()`, or any other SDK method.

    ```javascript theme={null}
    // Each call automatically keeps the session alive
    await tappd.track('button_click');
    // Session lastActivityAt is updated
    ```
  </Step>

  <Step title="Session Expires">
    The session ends when the user is inactive for longer than the configured timeout, closes the tab, or navigates away. The next interaction starts a fresh session.
  </Step>
</Steps>

## Configuration

### Setting the Timeout

Pass the `sessionTimeout` option (in minutes) when you initialize the SDK:

```javascript theme={null}
const tappd = new TappdSDK({
  appId: 'YOUR_APP_ID',
  sessionTimeout: 60 // 60 minutes instead of the default 30
});
```

### Recommended Timeouts by Use Case

<CardGroup cols={2}>
  <Card title="E-commerce" icon="cart-shopping" href="/web-sdk/sessions#setting-the-timeout">
    **30 minutes** (default) — Matches typical shopping session length.
  </Card>

  <Card title="SaaS Applications" icon="browser" href="/web-sdk/sessions#setting-the-timeout">
    **60 minutes** — Users work in the app for longer periods without triggering events.
  </Card>

  <Card title="Content Sites" icon="newspaper" href="/web-sdk/sessions#setting-the-timeout">
    **15 minutes** — Readers consume content quickly and bounce frequently.
  </Card>

  <Card title="Games" icon="gamepad" href="/web-sdk/sessions#setting-the-timeout">
    **10 minutes** — Short, intense activity bursts define a play session.
  </Card>
</CardGroup>

## Getting Session Information

### Read the Current Session ID

`getSessionId()` returns the current session ID as a string, or `null` if no session is active yet.

```javascript theme={null}
const sessionId = tappd.getSessionId();
console.log('Current session:', sessionId);
// Output: 'sess_abc123def456'  — or null if the session hasn't started yet
```

### Session Data in Every Event

Every event you track automatically includes session context — you don't need to attach it manually:

```javascript theme={null}
await tappd.track('purchase', { amount: 99.99 });
// The event payload automatically includes:
// - sessionId: 'sess_abc123def456'
// - sessionStartTime: 1234567890
// - sessionDuration: 120  (seconds since session started)
```

### Session Data Structure

Each session carries the following properties, which are automatically included on every event:

```javascript theme={null}
{
  sessionId: 'sess_abc123def456',
  startedAt: 1234567890000,    // Timestamp (ms)
  lastActivityAt: 1234567895000 // Timestamp (ms)
}
```

## SPA (Single Page Application) Support

The SDK handles client-side routing automatically so your session and page view tracking stays accurate in React, Vue, Angular, and any other SPA framework.

<Tabs>
  <Tab title="Automatic Tracking (Default)">
    When `autoTrack` is enabled (the default), the SDK listens to `history.pushState()`, `history.replaceState()`, and `popstate` events and tracks page views for every route change.

    ```javascript theme={null}
    const tappd = new TappdSDK({
      appId: 'YOUR_APP_ID',
      autoTrack: true // This is the default
    });

    // The SDK automatically tracks:
    // - Initial page load
    // - history.pushState() calls
    // - history.replaceState() calls
    // - popstate events (back/forward navigation)
    ```
  </Tab>

  <Tab title="Manual Tracking">
    If you set `autoTrack: false`, hook into your router's navigation guard and call `trackPageView()` yourself:

    ```javascript theme={null}
    const tappd = new TappdSDK({
      appId: 'YOUR_APP_ID',
      autoTrack: false
    });

    // Vue Router example
    router.beforeEach((to, from) => {
      tappd.trackPageView(to.fullPath, {
        from: from.fullPath,
        routeName: to.name
      });
    });
    ```
  </Tab>
</Tabs>

## Page Visibility API

The SDK respects the browser's Page Visibility API so session time is accurate even when users multitask:

* **Tab hidden**: Session activity is paused — idle time doesn't count against the timeout.
* **Tab visible again**: The SDK checks whether the session has expired and starts a new one if needed.

<Note>
  This behavior is automatic. You don't need to configure anything for it to work.
</Note>

## Session vs. User

Sessions and users are distinct concepts in Tappd:

| Concept     | Scope                    | Persistence                        |
| ----------- | ------------------------ | ---------------------------------- |
| **Session** | A single browser session | Starts/ends with activity in a tab |
| **User**    | An identified person     | Persists across many sessions      |

```javascript theme={null}
// Day 1: User opens the site anonymously
// → Session 1 starts

// User logs in
await tappd.identify({ external_id: 'user_123', email: 'john@example.com' });
// → Still Session 1, but now identified

// User closes the browser and returns the next day
// → Session 2 starts, still identified as user_123
```

<Tip>
  Call `identify()` as early as possible so that events within the current session are attributed to the correct user.
</Tip>
