> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.vitablehealth.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.vitablehealth.com/_mcp/server.

# Employee Dashboard Widget

> Embed Vitable's employee benefits dashboard into your application with the Vitable Connect SDK.

![Employee enrollment flow — plan selection step](/_fern-img/c12094768e882dd350d42d59357e0d6e49c3c11c28ded44bb495f5ce0c048dbe.webp)

The Employee Dashboard Widget gives an employee Vitable's complete benefits experience inside your application. It requires an **employee-bound** access token.

## Before You Begin

* Complete the shared [Vitable Drops setup](/drops/get-started).
* Create the employee through the Vitable API and store their `empl_` ID.
* Configure the provider with `createTokenFetcher("employee", employeeId)`.

## Add the Widget

```typescript
import { EmployeeViewWidget } from "@vitable-inc/drops/react"

function EmployeeDashboard() {
  return (
    <EmployeeViewWidget
      height="800px"
      onReady={() => console.log("Widget ready")}
      onEnrollmentComplete={(enrollments) => {
        console.log("Enrollment complete", enrollments)
      }}
      onError={(code, message) => {
        console.error("Widget error", code, message)
      }}
    />
  )
}
```

Place `EmployeeViewWidget` inside the `VitableConnectProvider` configured for the current employee.

## Props

### Layout

| Prop        | Type               | Default   | Purpose                             |
| ----------- | ------------------ | --------- | ----------------------------------- |
| `width`     | `string \| number` | `"100%"`  | Iframe width                        |
| `height`    | `string \| number` | `"600px"` | Iframe height                       |
| `className` | `string`           | —         | CSS class applied to the iframe     |
| `style`     | `CSSProperties`    | —         | Inline styles applied to the iframe |

### Events

| Prop                     | Signature                                 | When it fires                                     |
| ------------------------ | ----------------------------------------- | ------------------------------------------------- |
| `onReady`                | `() => void`                              | The iframe is loaded and ready                    |
| `onEmployeeViewReady`    | `() => void`                              | The employee interface is visible and interactive |
| `onEnrollmentComplete`   | `(enrollments) => void`                   | The employee completes an enrollment flow         |
| `onQleSubmitted`         | `(eventType: string) => void`             | The employee submits a qualifying life event      |
| `onAppointmentScheduled` | `(visitReasonName: string) => void`       | The employee schedules an appointment             |
| `onTokenExpired`         | `() => void`                              | A token expires; the SDK still attempts refresh   |
| `onAuthError`            | `(code: string, message: string) => void` | Authentication fails                              |
| `onError`                | `(code: string, message: string) => void` | Any widget error occurs                           |

`onEnrollmentComplete` receives one item per selected plan with the enrollment ID, benefit code, and status.

## Switch Employees Safely

Set the provider's `contextKey` to the active employee ID. When the employee changes, the SDK discards the old session and asks your backend for a newly bound token:

```typescript
import { useCallback } from "react"

function EmployeeSession({ currentEmployeeId }: { currentEmployeeId: string }) {
  const fetchToken = useCallback(
    createTokenFetcher("employee", currentEmployeeId),
    [currentEmployeeId],
  )

  return (
    <VitableConnectProvider
      baseUrl={VITABLE_WIDGET_URL}
      fetchToken={fetchToken}
      contextKey={currentEmployeeId}
    >
      <EmployeeViewWidget />
    </VitableConnectProvider>
  )
}
```

> **Warning**
>
> Do not render the widget until your backend has confirmed that the signed-in user may access `currentEmployeeId`.