WebSDK

JavaScript API

Complete reference for all FanID Widget methods, events, and types.

The FanID Widget exposes a global FanIDWidget object with methods for gating, authentication, and event handling.

Initialization

FanIDWidget.init(config)

Initialize the widget. Must be called once before using any other methods (except on() — see Events below). baseUrl is required.

FanIDWidget.init({
  baseUrl: 'https://your-org.fanid.co',
  floatingWidget: false,
  gatedContent: {
    style: 'blur',
  },
})

FanIDWidget.destroy()

Unmount the widget, remove all gates, and clean up.

FanIDWidget.destroy()

FanIDWidget.isInitialized()

Returns true if the widget has been initialized.

if (FanIDWidget.isInitialized()) {
  // Safe to call gating methods
}

Floating Widget

FanIDWidget.showFloatingWidget()

Programmatically show the floating sign-in/profile panel, even if floatingWidget: false or autoShow: false was set during init. Also clears any persisted "user closed" flag, so the panel becomes visible even when persistClose: 'persistent' is active.

FanIDWidget.showFloatingWidget()

FanIDWidget.hideFloatingWidget()

Programmatically hide the floating panel at any time. Does not set the persisted close flag — use this for temporary hides. User-initiated close (× button) is what writes to session/localStorage.

FanIDWidget.hideFloatingWidget()

FanIDWidget.setFloatingWidgetPosition(position)

Change the floating panel's position at runtime. Accepts 'top-left', 'top-right', 'bottom-left', 'bottom-right', or 'center'. If the panel is currently mounted, it is remounted with the new position (re-runs the entrance animation).

FanIDWidget.setFloatingWidgetPosition('bottom-right')

Example: custom sign-in button

FanIDWidget.init({ baseUrl: 'https://your-org.fanid.co', floatingWidget: false })

document.getElementById('my-signin-btn').addEventListener('click', () => {
  FanIDWidget.showFloatingWidget()
})

Example: persistent dismiss

// Once user closes, widget stays hidden across reloads until your app re-opens it
FanIDWidget.init({
  baseUrl: 'https://your-org.fanid.co',
  floatingWidget: { persistClose: 'persistent' },
})

// Your app can bring it back on demand
document.getElementById('signin-link').addEventListener('click', () => {
  FanIDWidget.showFloatingWidget()
})

Gated Content

FanIDWidget.gate(target, options?)

Gate a DOM element by CSS selector or reference.

ParameterTypeDescription
targetstring | HTMLElementCSS selector or DOM element
options.placeholderobject{ title, message, buttonText } overrides
options.stylestring'blur', 'gradient', or 'cover'
options.blurAmountnumberBlur intensity in pixels
options.minHeightnumberMinimum height for the gate container
options.teaserHeightnumberVisible teaser height (gradient mode)
FanIDWidget.gate('#stats', {
  placeholder: { title: 'Premium Stats' },
  style: 'gradient',
  minHeight: 300,
})

FanIDWidget.ungate(target)

Remove gating from an element.

FanIDWidget.ungate('#stats')

FanIDWidget.element(config)

Gate an element using a config object (alternative to gate()).

FanIDWidget.element({
  el: '#premium-section',
  placeholder: { title: 'Premium', buttonText: 'Unlock' },
  style: 'blur',
})

FanIDWidget.isGated(target)

Check if an element is currently gated. Returns boolean.

FanIDWidget.isGated('#stats') // true | false

FanIDWidget.gateFullPage(options?)

Display a full-viewport gating overlay. See Full-Page Gating.

FanIDWidget.ungateFullPage()

Remove the full-page gating overlay.

Authentication

FanIDWidget.isAuthenticated()

Check if the current user is authenticated. Returns Promise<boolean>.

const loggedIn = await FanIDWidget.isAuthenticated()

FanIDWidget.getProfile()

Get the authenticated user's profile. Returns Promise<SubscriberModel | null>.

The profile object includes:

FieldTypeDescription
firstNamestringUser's first name
lastNamestringUser's last name
emailstringUser's email address
phonestring | nullPhone number
countryCodestringCountry code
birthdatestring | nullDate of birth
activebooleanAccount active status
const profile = await FanIDWidget.getProfile()
if (profile) {
  console.log(`Hello, ${profile.firstName} ${profile.lastName}`)
  console.log(`Email: ${profile.email}`)
}

FanIDWidget.getOrganization()

Get the current organization that the widget was initialized against. Returns OrganizationModel | null synchronously — null before the widget has finished initializing or when the organization could not be resolved.

The returned object exposes the tenant's branding (title, subtitle, logo URL, primary/accent colors) and identity (id, name, domainName). Use it to label your own UI (header sign-in CTAs, account menus, etc.) without re-fetching /api/subscriber/organization.

FieldTypeDescription
idstringTenant ID
namestringDisplay name (e.g. "FanID")
domainNamestringTenant domain (e.g. "demo.fanid.co")
branding.titlestring | nullBrand title (e.g. "Demo FanID")
branding.subtitlestring | nullBrand subtitle / tagline
branding.logoUrlstring | nullLogo URL
branding.primaryColorstring | nullPrimary brand color (hex)
branding.accentColorstring | nullAccent / secondary brand color (hex)

Gate access on the ready event — the organization is resolved during initialization:

FanIDWidget.on('ready', () => {
  const org = FanIDWidget.getOrganization()
  const label = org?.branding.title ?? org?.name ?? 'Sign in'
  document.getElementById('header-signin-btn').textContent = label
})

FanIDWidget.login()

Redirect the user to the FanID login page. The current page URL is passed as the return URL.

FanIDWidget.login()

FanIDWidget.logout()

Log the user out and re-gate all content. Returns Promise<void>.

await FanIDWidget.logout()

Events

FanIDWidget.on(event, callback)

Subscribe to a widget event. Can be called before init() — event handlers registered early will fire when the corresponding event occurs after initialization.

// Register before init — will fire when widget is ready
FanIDWidget.on('ready', () => {
  console.log('Widget initialized')
})

FanIDWidget.init({ baseUrl: 'https://your-org.fanid.co' })

FanIDWidget.off(event, callback)

Unsubscribe from a widget event. Pass the same function reference used in on().

const handler = (profile) => console.log('Welcome', profile.firstName)
FanIDWidget.on('auth:login', handler)

// Later
FanIDWidget.off('auth:login', handler)

Event reference

EventPayloadDescription
readynoneWidget initialization complete
auth:loginSubscriberModelUser authenticated
auth:logoutnoneUser logged out
gate:appliedHTMLElementGating overlay applied to an element
gate:revealHTMLElementGated content revealed after authentication
gate:clickHTMLElementUser clicked the sign-in button on a gate

Example: custom analytics

FanIDWidget.on('gate:click', (element) => {
  analytics.track('fanid_gate_click', {
    elementId: element.id,
    page: window.location.pathname,
  })
})

FanIDWidget.on('auth:login', (profile) => {
  analytics.identify(profile.email)
})

Example: reactive UI updates

FanIDWidget.on('auth:login', async () => {
  const profile = await FanIDWidget.getProfile()
  document.getElementById('user-name').textContent = profile.firstName
  document.getElementById('user-email').textContent = profile.email
})

FanIDWidget.on('auth:logout', () => {
  document.getElementById('user-name').textContent = ''
  document.getElementById('user-email').textContent = ''
})

Auth state on <body>

Whenever the user's auth state changes — on init, after login, after logout, and after a cross-tab session update — the widget toggles a data-fanid-authed attribute on <body>. Use it to drive CSS-only soft gating without subscribing to events:

[data-fanid-locked] { display: none; }
body[data-fanid-authed] [data-fanid-locked] { display: block; }

See Soft Gating with CSS for the full pattern.

Cross-tab sync

The widget watches the storage event for changes to its session entry. If the user signs in or out in one tab, every other tab on the same origin re-checks the session, updates the body attribute, and emits the matching auth:login or auth:logout event. This is automatic — no API call from your side is required to keep tabs in sync.

Styling

All gated content CSS properties are configurable via --fanid-gate-* custom properties. See the complete styling reference for all available variables.

wmt-fanid-protected {
  --fanid-gate-panel-bg: #1a1a2e;
  --fanid-gate-button-bg: #e94560;
  --fanid-gate-title-color: white;
}

TypeScript

When using the npm package, all types are exported:

import type {
  BrandingSettingsModel,
  FloatingWidgetConfig,
  FloatingWidgetPersistClose,
  FloatingWidgetPosition,
  OrganizationModel,
  Transport,
  WidgetConfig,
} from '@wmt-fanid/widget'
import type { GatedContentConfig } from '@wmt-fanid/widget/dist/state'
import type { SubscriberModel } from '@wmt-fanid/widget/dist/types'

Transport is the union 'cookie' | 'bearer' and is the type of the optional transport field on WidgetConfig.

Copyright © 2026