Incentive Widget reference →

Embedding & auth

Widgets are installed as an ordinary npm dependency and imported as plain React components. Getting one on the page is two steps: install @fynxt/incentive-widgets, then authenticate the user and pass the resulting tokens into the widget as props.

Private package — registry access required

@fynxt/incentive-widgets is not on the public npm registry. Complete the two steps below before following this guide.

  1. Contact FYNXT Get your Azure Artifacts registry URL and a Personal Access Token (PAT).
  2. Add auth to ~/.npmrc Base64-encode your PAT, then paste the block below into your user-level ~/.npmrc.
    ~/.npmrc — auth token
    
    ; begin auth token
    //tech4jc.pkgs.visualstudio.com/c8171350-b496-4eb3-8045-6d8e29abce0b/_packaging/incentive-widgets/npm/registry/:username=tech4jc
    //tech4jc.pkgs.visualstudio.com/c8171350-b496-4eb3-8045-6d8e29abce0b/_packaging/incentive-widgets/npm/registry/:_password=[BASE64_ENCODED_PERSONAL_ACCESS_TOKEN]
    //tech4jc.pkgs.visualstudio.com/c8171350-b496-4eb3-8045-6d8e29abce0b/_packaging/incentive-widgets/npm/registry/:email=npm requires email to be set but doesn't use the value
    //tech4jc.pkgs.visualstudio.com/c8171350-b496-4eb3-8045-6d8e29abce0b/_packaging/incentive-widgets/npm/:username=tech4jc
    //tech4jc.pkgs.visualstudio.com/c8171350-b496-4eb3-8045-6d8e29abce0b/_packaging/incentive-widgets/npm/:_password=[BASE64_ENCODED_PERSONAL_ACCESS_TOKEN]
    //tech4jc.pkgs.visualstudio.com/c8171350-b496-4eb3-8045-6d8e29abce0b/_packaging/incentive-widgets/npm/:email=npm requires email to be set but doesn't use the value
    ; end auth token
Scope it, don't override the default registry. A bare registry= line would route all your packages — React, Next.js, everything — through FYNXT's feed. Map only the @fynxt:registry= scope so everything else still resolves from npm.

Widgets are built against your app's own copies of a few libraries — install these peers if you don't already have them: react and react-dom (^18 or ^19), recharts.

Import the stylesheet once. The package ships one combined CSS file covering every widget — @fynxt/incentive-widgets/widget.css. Import it a single time somewhere that always loads (your root layout, _app, or global CSS entry point) — widgets render unstyled if you skip this, regardless of which widget you import.

Authenticate and pass identity

There's no embed-token attribute here — your host app authenticates the user itself against the FYNXT auth API, then passes the resulting tokens into the widget as regular React props. Use the demo broker app's lib/auth.ts as the reference implementation — call its exported login(username, password, tenantSlug) rather than writing your own request:

  1. login() posts to /login (base URL https://incentive-program-app.fynxt.com//api/auth) with { username, password } and an X-Tenant-Slug header identifying the tenant.
  2. A non-2xx response throws, with the server's message/error (or raw body) included in the error text — surface that to the user rather than a generic failure.
  3. On success it reads accessToken/refreshToken from the response (unwrapping a data envelope if present) and persists both to localStorage.
  4. It then decodes the access token's JWT payload with decodeJWT() — a plain base64url decode of the payload segment, not a signature check — and separately caches authId / activeProfileId (from the token's id claim), authProfileType and permissions in localStorage for the rest of the app to read.
  5. Render the widget, passing the access token, refresh token and authId as props.
Storing tokens client-side. The demo persists tokens and derived claims in localStorage for simplicity. Apply your own app's security practices around token storage and refresh in production.

TypeScript

Each widget's shipped .d.ts is currently named after its source file (e.g. reward-dashboard-widget.d.ts), not the numbered bundle you actually import — see the React component reference. Until that's aligned upstream, add an ambient module declaration so TypeScript stops flagging the numbered imports as untyped:

// types/fynxt-incentive-widgets.d.ts
declare module "@fynxt/incentive-widgets/widget*.js";

Make sure your tsconfig.json include covers the folder you put this in (a top-level **/*.ts pattern already will).