> 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.

# Employer Benefits Widget

> Embed Vitable's benefits administration dashboard into your application so employers can manage plans, enrollments, and coverage.

![Employer benefits administration dashboard](/_fern-img/253404f44e063a1c8b9e4c2bd7add4a22371e1d5bd878cb6efbfd6249ac3b244.webp)

Employer Benefits gives HR administrators enrollment visibility, plan assignment tools, and coverage information inside your application. It requires an **employer-bound** access token.

## Before You Begin

* Complete the shared [Vitable Drops setup](/drops/get-started).
* [Onboard the employer](/embedded_benefits/guides/employer-onboarding) and store its `empr_` ID.
* Configure the provider with `createTokenFetcher("employer", employerId)`.

## Add the Widget

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

function BenefitsAdmin() {
  return (
    <EmployerBenefitsWidget
      height="800px"
      onReady={() => console.log("Widget ready")}
      onError={(code, message) => {
        console.error("Widget error", code, message)
      }}
    />
  )
}
```

Place `EmployerBenefitsWidget` inside the `VitableConnectProvider` configured for the current employer.

## 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                    |
| `onEmployerBenefitsReady` | `() => void`                              | The benefits interface is visible and interactive |
| `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                           |

## Switch Employers Safely

Use the current employer ID as the provider's `contextKey`. Changing it resets the session and fetches a token bound to the new employer:

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

function EmployerSession({ currentEmployerId }: { currentEmployerId: string }) {
  const fetchToken = useCallback(
    createTokenFetcher("employer", currentEmployerId),
    [currentEmployerId],
  )

  return (
    <VitableConnectProvider
      baseUrl={VITABLE_WIDGET_URL}
      fetchToken={fetchToken}
      contextKey={currentEmployerId}
    >
      <EmployerBenefitsWidget />
    </VitableConnectProvider>
  )
}
```

The same provider can also render [Employer Billing](/drops/employer-billing) because both widgets use the same employer scope.