Entitlements Integration (Vanilla.js)

🚧

Prerequisite

Minimum required version : 6.175.0

Configuring Entitlements with Vanilla JS

Use the following code to configure entitlements with Vanilla JS.

import { initialize } from "@frontegg/js";

const app = initialize({
    contextOptions: {
        //baseUrl: ,
        //clientId: ,
    },
    entitlementsOptions: {
        enabled: true,
    },
});

Note that an exception will be triggered if you don’t configure entitlements before using the functions.

API Calls

The following API calls can be performed after configuring Entitlements with React.

  • useFeatureEntitlements - checks whether a user is entitled to feature access.
  • usePermissionEntitlements - checks whether a user is entitled to permission.
  • useEntitlements - checks whether a user is entitled to a feature or permission.

Custom Attributes

Frontegg allows you to create custom attributes for users (learn more about creating custom attributes. Attributes can be used for Feature Flagging purposes and in Entitlement API calls within a customAttributes object. The customAttributes object is optional and comprised of key-value pairs with possible values of string | number | boolean | Date, like so:

app.getFeatureEntitlements('feature-x', { attr1: 'val1', attr2: 'val2' });
import { Entitlement, CustomAttributes } from '@frontegg/types';

getFeatureEntitlements(key: string, customAttributes?:CustomAttributes) => Entitlement
getPermissionEntitlements(key: string, customAttributes?:CustomAttributes) => Entitlement
getEntitlements(options: EntitledToOptions, customAttributes?:CustomAttributes) => Entitlement

🚧

Hooks Usage

Hooks should be called for authenticated users only.

Using the subscribeStateChanged Function

Under the hood, Frontegg uses redux to manage our state. When using redux’s store.subscribe, redux doesn’t promise that the callback will be called when changes happen ("...Redux adds a change listener. It will be called any time an action is dispatched, and some part of the state tree may potentially have changed" redux docs), so we encourage that you use subscribeStateChanged to ensure that the callback performs when changes occur.

The following example shows how to use exposed functions for user subscription to receive store updates:

app.store.subscribeStateChanged((state) => {
    if (state.auth.isAuthenticated) {
        const {
            isEntitled: isFeature1Entitled,
            justification: justificationFeature1,
        } = app.getFeatureEntitlements("feature1");

        const {
            isEntitled: isPermission1Entitled,
            justification: justificationPermission1,
        } = app.getPermissionEntitlements("permission1");

        const {
            isEntitled: isFeature2Entitled,
            justification: justificationFeature2,
        } = app.getEntitlements({ featureKey: "feature2" });

        const {
            isEntitled: isPermission2Entitled,
            justification: justificationPermission2,
        } = app.getEntitlements({ permissionKey: "fe.connectivity.*" });
    }
});

A full example including HTML:

// HTML file
<section fe-state="isAuthenticated">
    <section fe-state="isEntitled">Feature 1 entitled UI</section>

    <section fe-state="!isEntitled">Feature 1 NOT entitled UI</section>
</section>;

// js file
app.store.subscribeStateChanged((state) => {
    const isAuthenticated = state.auth.isAuthenticated;

    let styleHtml = "";

    if (isAuthenticated) {
        styleHtml += '[fe-state="isAuthenticated"] { }';
        styleHtml += '[fe-state="!isAuthenticated"] { display: none; }';
    } else {
        styleHtml += '[fe-state="isAuthenticated"] { display: none; }';
        styleHtml += '[fe-state="!isAuthenticated"] { }';
    }

    if (isAuthenticated) {
        const { isEntitled, justification } = app.getFeatureEntitlements(
            "feature1"
        );

        if (isEntitled) {
            styleHtml += '[fe-state="isEntitled"] { }';
            styleHtml += '[fe-state="!isEntitled"] { display: none; }';
        } else {
            styleHtml += '[fe-state="isEntitled"] { display: none; }';
            styleHtml += '[fe-state="!isEntitled"] { }';
        }
    }

    style.innerHTML = styleHtml;
});

Note that subscribeStateChanged is called for every store change. If you want to call subscribeStateChanged for specific changes only, then you can do the following:

let previousEntitlementsState;
app.store.subscribeStateChanged((state) => {
    const entitlementsState = state.auth.user?.entitlements;
    if (entitlementsState !== previousEntitlementsState) {
        previousEntitlementsState = entitlementsState;
        console.log("entitlements change - do something");
    }
});

Load on demand

You can also load entitlements on demand by using theloadEntitlements function, exposed from the FronteggApp:


app.loadEntitlements();

You can then pass a callback to let you know that the request was completed:

app.loadEntitlements((isSucceeded) => console.log(`request ${isSucceeded ? 'succeeded' : 'failed'}`)) }}>