Impersona Docs
Impersona Docs
HomePricingImpersona SDKQuickstartInstallationAuth StrategiesPermissions TestingTroubleshooting

IntegrationsDirectus IntegrationOutline IntegrationStrapi Integration

Installation

Prerequisites and minimum installation steps for the Impersona SDK.

This guide covers prerequisites, installation, and configuration in detail. If you want the shortest path to a working setup, start with the Quickstart.

Prerequisites

  • A running app with authentication (the SDK impersonates authenticated users — there's nothing to impersonate without auth)
  • A local environment where you can run and test requests
  • Access to your app's auth or session middleware (you may need to read the impersonation token header)
  • An Impersona project with a generated publishable key and your frontend origin in Allowed Origins

Install the SDK

npm install @impersona/sdk

Environment variables

Add your project credentials to your .env. Select your framework to see the correct variable prefix:

Required:

VITE_IMPERSONA_PROJECT_ID=proj_abc123
VITE_IMPERSONA_PUBLISHABLE_KEY=pk_test_xxxxxxxxxxxxxxxx

Optional (only if self-hosting):

VITE_IMPERSONA_API_BASE_URL=http://localhost:3002/api/v1

Required:

NEXT_PUBLIC_IMPERSONA_PROJECT_ID=proj_abc123
NEXT_PUBLIC_IMPERSONA_PUBLISHABLE_KEY=pk_test_xxxxxxxxxxxxxxxx

Optional (only if self-hosting):

NEXT_PUBLIC_IMPERSONA_API_BASE_URL=http://localhost:3002/api/v1

Required:

REACT_APP_IMPERSONA_PROJECT_ID=proj_abc123
REACT_APP_IMPERSONA_PUBLISHABLE_KEY=pk_test_xxxxxxxxxxxxxxxx

Optional (only if self-hosting):

REACT_APP_IMPERSONA_API_BASE_URL=http://localhost:3002/api/v1

If omitted, the SDK defaults to the hosted Impersona backend.

Configure the provider

Wrap your app with ImpersonaProvider and render ImpersonaWidget:

import { ImpersonaProvider } from '@impersona/sdk'
import { ImpersonaWidget } from '@impersona/sdk/widget'

export function App() {
  return (
    <ImpersonaProvider
      projectId={import.meta.env.VITE_IMPERSONA_PROJECT_ID}
      publishableKey={import.meta.env.VITE_IMPERSONA_PUBLISHABLE_KEY}
      apiBaseUrl={import.meta.env.VITE_IMPERSONA_API_BASE_URL || undefined}
      enabled={import.meta.env.DEV}
      refreshStrategy={{ type: 'reload' }}
    >
      {/* your app tree */}
      <ImpersonaWidget />
    </ImpersonaProvider>
  )
}
import { ImpersonaProvider } from '@impersona/sdk'
import { ImpersonaWidget } from '@impersona/sdk/widget'

export function App() {
  return (
    <ImpersonaProvider
      projectId={process.env.NEXT_PUBLIC_IMPERSONA_PROJECT_ID!}
      publishableKey={process.env.NEXT_PUBLIC_IMPERSONA_PUBLISHABLE_KEY!}
      apiBaseUrl={process.env.NEXT_PUBLIC_IMPERSONA_API_BASE_URL || undefined}
      enabled={process.env.NODE_ENV === 'development'}
      refreshStrategy={{ type: 'reload' }}
    >
      {/* your app tree */}
      <ImpersonaWidget />
    </ImpersonaProvider>
  )
}
import { ImpersonaProvider } from '@impersona/sdk'
import { ImpersonaWidget } from '@impersona/sdk/widget'

export function App() {
  return (
    <ImpersonaProvider
      projectId={process.env.REACT_APP_IMPERSONA_PROJECT_ID!}
      publishableKey={process.env.REACT_APP_IMPERSONA_PUBLISHABLE_KEY!}
      apiBaseUrl={process.env.REACT_APP_IMPERSONA_API_BASE_URL || undefined}
      enabled={process.env.NODE_ENV === 'development'}
      refreshStrategy={{ type: 'reload' }}
    >
      {/* your app tree */}
      <ImpersonaWidget />
    </ImpersonaProvider>
  )
}

Provider props

PropRequiredPurpose
projectIdYesMust match the project ID in the dashboard
publishableKeyYesMust match the key generated in the dashboard
apiBaseUrlNoOverride the hosted backend URL (self-hosting only)
enabledNoGates the SDK on/off — use to disable in production
refreshStrategyNoHow the app refreshes after applying a preset (reload or soft)
tokenAdapterNoCustom fetch interceptor (see below)

Default adapter behavior

When no tokenAdapter is passed, the provider creates a FetchInterceptorAdapter with:

  • allowedOrigins: same-origin only — the adapter only patches requests to your app's own API
  • excludePatterns: [apiBaseUrl] — SDK-internal calls to the Impersona backend are automatically excluded so they use the publishable key, not the impersonation token

This default is correct for most setups where your frontend and API share the same origin.

Custom adapter (cross-origin APIs)

If your frontend and API are on different origins, you need a custom adapter:

import { useMemo } from 'react'
import { FetchInterceptorAdapter, ImpersonaProvider } from '@impersona/sdk'

export function App() {
  const apiBaseUrl =
    import.meta.env.VITE_IMPERSONA_API_BASE_URL || 'https://app.impersona.co.uk/api/v1'

  const adapter = useMemo(
    () =>
      new FetchInterceptorAdapter({
        allowedOrigins: ['https://api.myapp.com'],
        excludePatterns: [apiBaseUrl],
      }),
    [apiBaseUrl],
  )

  return (
    <ImpersonaProvider
      projectId={import.meta.env.VITE_IMPERSONA_PROJECT_ID}
      publishableKey={import.meta.env.VITE_IMPERSONA_PUBLISHABLE_KEY}
      apiBaseUrl={import.meta.env.VITE_IMPERSONA_API_BASE_URL || undefined}
      tokenAdapter={adapter}
      enabled={import.meta.env.DEV}
      refreshStrategy={{ type: 'reload' }}
    >
      {/* your app tree */}
    </ImpersonaProvider>
  )
}
import { useMemo } from 'react'
import { FetchInterceptorAdapter, ImpersonaProvider } from '@impersona/sdk'

export function App() {
  const apiBaseUrl =
    process.env.NEXT_PUBLIC_IMPERSONA_API_BASE_URL || 'https://app.impersona.co.uk/api/v1'

  const adapter = useMemo(
    () =>
      new FetchInterceptorAdapter({
        allowedOrigins: ['https://api.myapp.com'],
        excludePatterns: [apiBaseUrl],
      }),
    [apiBaseUrl],
  )

  return (
    <ImpersonaProvider
      projectId={process.env.NEXT_PUBLIC_IMPERSONA_PROJECT_ID!}
      publishableKey={process.env.NEXT_PUBLIC_IMPERSONA_PUBLISHABLE_KEY!}
      apiBaseUrl={process.env.NEXT_PUBLIC_IMPERSONA_API_BASE_URL || undefined}
      tokenAdapter={adapter}
      enabled={process.env.NODE_ENV === 'development'}
      refreshStrategy={{ type: 'reload' }}
    >
      {/* your app tree */}
    </ImpersonaProvider>
  )
}
import { useMemo } from 'react'
import { FetchInterceptorAdapter, ImpersonaProvider } from '@impersona/sdk'

export function App() {
  const apiBaseUrl =
    process.env.REACT_APP_IMPERSONA_API_BASE_URL || 'https://app.impersona.co.uk/api/v1'

  const adapter = useMemo(
    () =>
      new FetchInterceptorAdapter({
        allowedOrigins: ['https://api.myapp.com'],
        excludePatterns: [apiBaseUrl],
      }),
    [apiBaseUrl],
  )

  return (
    <ImpersonaProvider
      projectId={process.env.REACT_APP_IMPERSONA_PROJECT_ID!}
      publishableKey={process.env.REACT_APP_IMPERSONA_PUBLISHABLE_KEY!}
      apiBaseUrl={process.env.REACT_APP_IMPERSONA_API_BASE_URL || undefined}
      tokenAdapter={adapter}
      enabled={process.env.NODE_ENV === 'development'}
      refreshStrategy={{ type: 'reload' }}
    >
      {/* your app tree */}
    </ImpersonaProvider>
  )
}

Important: When creating a custom adapter, you must include apiBaseUrl in excludePatterns. Otherwise the adapter injects the impersonation token into SDK-internal calls, causing auth failures on preset fetches. Also avoid path fragments like /api/v1 in excludePatterns — they match your host app's own routes too, preventing impersonation tokens from reaching your API.

Host integration (required)

Impersona can send a token, but your host must know how to read it. Choose one of these patterns:

  1. Authorization swap — Impersona replaces the Authorization header. Your API already reads Authorization: Bearer <token>, so no backend changes are needed.

  2. Custom header — Impersona sends X-Impersona-Token (or another header you choose). Your host reads that header and resolves the impersonated identity. Requires a small middleware change.

  3. Cookie session — Your host reads an Impersona token header and creates a session. Useful for apps that rely on cookie-based auth.

See Auth Strategies for detailed guidance on each pattern.

Environment safety

The enabled prop is the primary gate. Set it to a development-only condition:

enabled={import.meta.env.DEV}
enabled={process.env.NODE_ENV === 'development'}

When enabled is false, the SDK renders nothing and does not intercept any requests.

For additional strategies (conditional imports, build-time exclusion, feature flags), see the environment safety section in the configuration alignment reference.

Quickstart

Get Impersona running locally in minutes.

Auth Strategies

Choose the identity strategy that matches your app's auth model.

On this page

PrerequisitesInstall the SDKEnvironment variablesConfigure the providerProvider propsDefault adapter behaviorCustom adapter (cross-origin APIs)Host integration (required)Environment safety