MCPcopy Index your code
hub / github.com/Unleash/unleash-nextjs-sdk

github.com/Unleash/unleash-nextjs-sdk @v1.6.7

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.6.7 ↗ · + Follow
132 symbols 324 edges 73 files 0 documented · 0%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Unleash Next.js SDK

Unleash is a private, secure, and scalable feature management platform built to reduce the risk of releasing new features and accelerate software development. This Next.js SDK is designed to help you integrate with Unleash and evaluate feature flags inside your application.

You can use this client with Unleash Enterprise or Unleash Open Source.

Setup

Installation

To install, simply run:

npm install @unleash/nextjs
# or
yarn add @unleash/nextjs
# or
pnpm add @unleash/nextjs

There is an ./example project that you can deploy to Vercel or edit in CodeSandbox.

Environment variables

This package will attempt to load configuration from Next.js Environment variables.

When using Unleash client-side, with <FlagProvider /> or getFrontendFlags() configure:

  • NEXT_PUBLIC_UNLEASH_FRONTEND_API_URL. URL should end with /api/frontend or /proxy
  • NEXT_PUBLIC_UNLEASH_FRONTEND_API_TOKEN client-side API token if you're using the front-end API, or a proxy client key if you're using a proxy
  • Using Edge is the same as using the frontend API, so you'll need a FRONTEND_API_TOKEN, and your URL should end with /api/frontend.

If using server-side (SSR, SSG, API), using getDefinitions() and evaluateFlags(), set:

Detailed explanation

Prefixable Variable Default
NEXT_PUBLIC_ UNLEASH_SERVER_API_URL http://localhost:4242/api
NEXT_PUBLIC_ UNLEASH_FRONTEND_API_URL <(NEXT_PUBLIC_)UNLEASH_SERVER_API_URL>/frontend
No UNLEASH_SERVER_API_TOKEN default:development.unleash-insecure-api-token
No UNLEASH_SERVER_INSTANCE_ID undefined
NEXT_PUBLIC_ UNLEASH_FRONTEND_API_TOKEN default:development.unleash-insecure-frontend-api-token
NEXT_PUBLIC_ UNLEASH_APP_NAME nextjs

If you plan to use configuration in the browser, add NEXT_PUBLIC_ prefix. If both are defined and available, private variable takes priority. You can use both to have different values on client-side and server-side.


💡 Usage with GitLab's feature flags: To use this SDK with GitLab Feature Flags, use UNLEASH_SERVER_INSTANCE_ID instead of UNLEASH_SERVER_API_TOKEN to authorize with GitLab's service.


Usage

A). App router

This package is ready for server-side use with App Router.

Refer to ./example/README.md#App-router for an implementation example.

import { cookies } from "next/headers";
import { evaluateFlags, flagsClient, getDefinitions } from "@unleash/nextjs";

const getFlag = async () => {
  const cookieStore = cookies();
  const sessionId =
    cookieStore.get("unleash-session-id")?.value ||
    `${Math.floor(Math.random() * 1_000_000_000)}`;

  const definitions = await getDefinitions({
    fetchOptions: {
      next: { revalidate: 15 }, // Cache layer like Unleash Proxy!
    },
  });

  const { toggles } = evaluateFlags(definitions, {
    sessionId,
  });
  const flags = flagsClient(toggles);

  return flags.isEnabled("nextjs-example");
};

export default async function Page() {
  const isEnabled = await getFlag();

  return (



      Feature flag is{" "}
      <strong>
        <code>{isEnabled ? "ENABLED" : "DISABLED"}</code>
      </strong>
      .



  );
}

B). Middleware

It's possible to run this SDK in Next.js Edge Middleware. This is a great use case for A/B testing, where you can transparently redirect users to different pages based on a feature flag. Target pages can be statically generated, improving performance.

Refer to ./example/README.md#Middleware for an implementation example.

C). Client-side only - simple use case and for development purposes (CSR)

Fastest way to get started is to connect frontend directly to Unleash. You can find out more about direct Front-end API access in our documentation, including a guide on how to setup a client-side SDK key.

Important: Hooks and provider are only available in @unleash/nextjs/client.

import type { AppProps } from "next/app";
import { FlagProvider } from "@unleash/nextjs/client";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <FlagProvider>
      <Component {...pageProps} />
    </FlagProvider>
  );
}

With <FlagProvider /> in place you can now use hooks like: useFlag, useVariant, or useFlagsStatus to block rendering until flags are ready.

import { useFlag } from "@unleash/nextjs/client";

const YourComponent = () => {
  const isEnabled = useFlag("nextjs-example");

  return <>{isEnabled ? "ENABLED" : "DISABLED"}</>;
};

Optionally, you can configure FlagProvider with the config prop. It will take priority over environment variables.

<FlagProvider
  config={{
    url: "http://localhost:4242/api/frontend", // replaces NEXT_PUBLIC_UNLEASH_FRONTEND_API_URL
    clientKey: "<Frontend_API_token>", // replaces NEXT_PUBLIC_UNLEASH_FRONTEND_API_TOKEN
    appName: "nextjs", // replaces NEXT_PUBLIC_UNLEASH_APP_NAME

    refreshInterval: 15, // additional client configuration
    // see https://github.com/Unleash/unleash-proxy-client-js#available-options
  }}
>

If you only plan to use Unleash client-side React SDK now also works with Next.js. Check documentation there for more examples.

D). Static Site Generation, optimized performance (SSG)

With same access as in the client-side example above you can resolve Unleash feature flags when building static pages.

import {
  flagsClient,
  getDefinitions,
  evaluateFlags,
  getFrontendFlags,
  type IVariant,
} from "@unleash/nextjs";
import type { GetStaticProps, NextPage } from "next";

type Data = {
  isEnabled: boolean;
  variant: IVariant;
};

const ExamplePage: NextPage<Data> = ({ isEnabled, variant }) => (
  <>
    Flag status: {isEnabled ? "ENABLED" : "DISABLED"}



    Variant: {variant.name}
  </>
);

export const getStaticProps: GetStaticProps<Data> = async (_ctx) => {
  /* Using server-side SDK: */
  const definitions = await getDefinitions();
  const context = {}; // optional, see https://docs.getunleash.io/reference/unleash-context
  const { toggles } = evaluateFlags(definitions, context);

  /* Or with the proxy/front-end API */
  // const { toggles } = await getFrontendFlags({ context });

  const flags = flagsClient(toggles);

  return {
    props: {
      isEnabled: flags.isEnabled("nextjs-example"),
      variant: flags.getVariant("nextjs-example"),
    },
  };
};

export default ExamplePage;

The same approach will work for ISR (Incremental Static Regeneration).

Both getDefinitions() and getFrontendFlags() can take arguments overriding URL, token and other request parameters.

E). Server Side Rendering (SSR)

import {
  flagsClient,
  evaluateFlags,
  getDefinitions,
  type IVariant,
} from "@unleash/nextjs";
import type { GetServerSideProps, NextPage } from "next";

type Data = {
  isEnabled: boolean;
};

const ExamplePage: NextPage<Data> = ({ isEnabled }) => (
  <>Flag status: {isEnabled ? "ENABLED" : "DISABLED"}</>
);

export const getServerSideProps: GetServerSideProps<Data> = async (ctx) => {
  const sessionId =
    ctx.req.cookies["unleash-session-id"] ||
    `${Math.floor(Math.random() * 1_000_000_000)}`;
  ctx.res.setHeader("set-cookie", `unleash-session-id=${sessionId}; path=/;`);

  const context = {
    sessionId, // needed for stickiness
    // userId: "123" // etc
  };

  const definitions = await getDefinitions(); // Uses UNLEASH_SERVER_API_URL
  const { toggles } = evaluateFlags(definitions, context);

  const flags = flagsClient(toggles); // instantiates a static (non-syncing) unleash-proxy-client

  return {
    props: {
      isEnabled: flags.isEnabled("nextjs-example")
    },
  };
};

export default ExamplePage;

F). Bootstrapping / rehydration

You can bootstrap Unleash React SDK to have values loaded from the start. Initial value can be customized server-side.

import App, { AppContext, type AppProps } from "next/app";
import {
  FlagProvider,
  getFrontendFlags,
  type IMutableContext,
  type IToggle,
} from "@unleash/nextjs";

type Data = {
  toggles: IToggle[];
  context: IMutableContext;
};

export default function CustomApp({
  Component,
  pageProps,
  toggles,
  context,
}: AppProps & Data) {
  return (
    <FlagProvider
      config={{
        bootstrap: toggles,
        context,
      }}
    >
      <Component {...pageProps} />
    </FlagProvider>
  );
}

CustomApp.getInitialProps = async (ctx: AppContext) => {
  const context = {
    userId: "123",
  };

  const { toggles } = await getFrontendFlags(); // use Unleash Proxy

  return {
    ...(await App.getInitialProps(ctx)),
    bootstrap: toggles,
    context, // pass context along so client can refetch correct values
  };
};

Server-side flags and metrics (new in v1.5.0)

Next.js applications using Server-Side Rendering (SSR) are often deployed in serverless or short-lived environments, such as Vercel. This creates challenges for server-side metrics reporting.

Typically, Unleash backend SDKs (like the Node.js SDK run in long-lived processes, allowing them to cache metrics locally and send them to the Unleash API or Edge API at scheduled intervals.

However, in some short-lived serverless environments where Next.js is commonly hosted (e.g., Vercel), there is no persistent in-memory cache across multiple requests. As a result, metrics must be reported on each request.

To address this, the SDK provides a sendMetrics function that can be called wherever needed, but it should be executed after feature flag checks client.isEnabled() or variant checks client.getVariant().

We also recommend setting up the Edge API in front of your Unleash API. This helps protect your Unleash API from excessive traffic caused by per-request metrics reporting.

const enabled = flags.isEnabled("nextjs-example");

await flags.sendMetrics();

No setInterval support (e.g. Vercel)

If your runtime does not allow setInterval calls then you can report metrics on each request as shown below. Consider using Unleash Edge in this scenario.

Next.js 15 and newer

Latest versions of Next.js allow to run code after the response is sent, with after function.

import { after } from 'next/server'
// ...
export default async function Page() {

  // ...
  const flags = flagsClient(evaluated.toggles)
  const isEnabled = flags.isEnabled("example-flag")

  after(async () => {
    flags.sendMetrics()
  })

  return (
    // ...
  )
}

Next.js 14 and older

App router

import {evaluateFlags, flagsClient, getDefinitions,} from "@unleash/nextjs";

export default async function Page() {
  const definitions = await getDefinitions({
    fetchOptions: {
      next: { revalidate: 15 }, // Cache layer like Unleash Proxy!
    },
  });
  const context = {};
  const { toggles } = evaluateFlags(definitions, context);
  const flags = flagsClient(toggles);

  const enabled = flags.isEnabled("nextjs-example");

  // await client.sendMetrics().catch(() => {}); // blocking metrics
  flags.sendMetrics().catch(() => {}); // non-blocking metrics

  return  <>Flag status: {enabled ? "ENABLED" : "DISABLED"}</>
}

Page router

```tsx import { evaluateFlags, flagsClient, getDefinitions } from "@unleash/nextjs"; import type { GetServerSideProps, NextPage } from "next";

type Data = { isEnabled: boolean; };

export const getServerSideProps: GetServerSideProps = async () => { const definitions = await getDefinitions(); const context = {}; const { toggles } = evaluateFlags(definitions, context); const flags = flagsClient(toggles);

const enabled = flags.isEnabled("nextjs-example");

// await client.sendMetrics().catch(() => {}); // blocking metrics flags.sendMetrics().catch(() => {}); // non-blocking metrics

return { props: {

Extension points exported contracts — how you extend this code

Properties (Interface)
(no doc)
lib/src/core/client/context.ts
Context (Interface)
(no doc)
lib/src/core/client/context.ts
StrategyTransportInterface (Interface)
(no doc)
lib/src/core/client/strategy/strategy.ts
Constraint (Interface)
(no doc)
lib/src/core/client/strategy/strategy.ts
Segment (Interface)
(no doc)
lib/src/core/client/strategy/strategy.ts

Core symbols most depended-on inside this repo

getDefinitions
called by 21
lib/src/getDefinitions.ts
getDefaultClientConfig
called by 13
lib/src/utils.ts
flagsClient
called by 13
lib/src/flagsClient.ts
evaluateFlags
called by 10
lib/src/evaluateFlags.ts
isEnabled
called by 9
lib/src/core/client/strategy/strategy.ts
step
called by 9
lib/src/cli/__mocks__/helpers.ts
resolveContextValue
called by 7
lib/src/core/client/helpers.ts
removeTrailingSlash
called by 6
lib/src/utils.ts

Shape

Function 78
Method 28
Class 20
Interface 5
Enum 1

Languages

TypeScript100%

Modules by API surface

lib/src/core/client/strategy/strategy.ts19 symbols
lib/src/core/engine.ts9 symbols
lib/src/utils.ts8 symbols
lib/src/core/variant.ts7 symbols
lib/src/core/client/strategy/flexible-rollout-strategy.ts5 symbols
lib/src/core/client/helpers.ts5 symbols
lib/src/getDefinitions.ts4 symbols
lib/src/core/client/strategy/user-with-id-strategy.ts4 symbols
lib/src/core/client/strategy/remote-addresss-strategy.ts4 symbols
lib/src/core/client/strategy/gradual-rollout-user-id.ts4 symbols
lib/src/core/client/strategy/gradual-rollout-session-id.ts4 symbols
lib/src/core/client/strategy/gradual-rollout-random.ts4 symbols

For agents

$ claude mcp add unleash-nextjs-sdk \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page