Entitlements Integration (Next.js)

Harness the power of Frontegg's robust Entitlements Engine directly into the heart of your Next.js application, allowing you to effortlessly implement sophisticated, role-based, and attribute-based access controls with just a few lines of code.

ūüöß

Prerequisites

Minimum required @Frontegg/Next.js version for this feature is 8.0.16.

Configuring Entitlements with NextJS SDK

Use the following code to configure entitlements with NextJS SDK:

Next.js appDir Architecture

import { FronteggAppProvider } from '@frontegg/nextjs/app';

export default function RootLayout({ children }: { children: React.ReactNode }) {
    //...
    
    return (
      <html>
        <head></head>
        <body>
            {/* @ts-expect-error Server Component for more details visit: https://github.com/vercel/next.js/issues/42292 */}
            <FronteggAppProvider 
              //...
	            entitlementsOptions={{ enabled: true }}
	          >
                {children}
            </FronteggAppProvider>
        </body>
      </html>
    );
}

Next.js pages Architecture

import { withFronteggApp } from "@frontegg/nextjs/pages";

function CustomApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />;
}

export default withFronteggApp(CustomApp, {
  //...
  entitlementsOptions: { enabled: true }
});

API Calls

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

  • 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:

import { useFeatureEntitlements } from '@frontegg/nextjs';
useFeatureEntitlements('feature-x', { attr1: 'val1', attr2: 'val2' })
import { useFeatureEntitlements, usePermissionEntitlements, useEntitlements } from '@frontegg/nextjs';
import { Entitlement, CustomAttributes } from '@frontegg/types';

useFeatureEntitlements(key: string, customAttributes?:CustomAttributes) => Entitlement
usePermissionEntitlements(key: string, customAttributes?:CustomAttributes) => Entitlement
useEntitlements(options: EntitledToOptions, customAttributes?:CustomAttributes) => Entitlement

Creating Hooks

ūüöß

Hooks Usage

ūüößHooks Usage

  • Hooks should be called for authenticated users only.
  • An exception will be thrown if entitlements is not enabled before using hooks.
import {
  useFeatureEntitlements,
  usePermissionEntitlements,
  useEntitlements,
  useIsAuthenticated,
} from "@frontegg/nextjs";

const Page = () => {
  const isAuthenticated = useIsAuthenticated();

  return <>{isAuthenticated && <Entitlements />}</>;
};

const Entitlements = () => {
  const { isEntitled: isFEntitled, justification: fJust } =
    useFeatureEntitlements("feature-key");

  const { isEntitled: isPEntitled, justification: pJust } =
    usePermissionEntitlements("permission-key");

  const { isEntitled: isPEntitled2, justification: pJust2 } = useEntitlements({
    permissionKey: "permission-key",
  });

  const { isEntitled: isFEntitled2, justification: fJust2 } = useEntitlements({
    featureKey: "feature-key",
  });

  return (
    <>
      {isFEntitled && <div>A cool section</div>}
      {isPEntitled && <div>An awesome section</div>}
      {isPEntitled2 && <div>A mind-blowing section</div>}
      {isFEntitled2 && <div>Another section</div>}
    </>
  );
};

In case the user is not entitled to the feature or permission, the NotEntitledJustification when isEntitled is false will be one of the following enums:

export enum NotEntitledJustification {
  MISSING_PERMISSION = 'MISSING_PERMISSION',
  MISSING_FEATURE = 'MISSING_FEATURE',
  BUNDLE_EXPIRED = 'BUNDLE_EXPIRED',
}

Load on demand

The user can load entitlements on demand with the loadEntitlements saga:

const { loadEntitlements } = useAuthActions();

<button
    onClick={() => {
        loadEntitlements();
    }}
>
    Load entitlements
</button>;

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

const { loadEntitlements } = useAuthActions();

const onLoadEntitlements = () => {
    loadEntitlements({
        callback: (isSucceeded) =>
            console.log(`request ${isSucceeded ? "succeeded" : "failed"}`),
    });
};

<button onClick={onLoadEntitlements}>Load entitlements</button>;