Gathering detailed insights and metrics for @unleash/nextjs
Gathering detailed insights and metrics for @unleash/nextjs
Gathering detailed insights and metrics for @unleash/nextjs
Gathering detailed insights and metrics for @unleash/nextjs
unleash-client
Unleash Client for Node
unleash-proxy-client
A browser client that can be used together with the unleash-proxy.
@unleash/proxy-client-react
React interface for working with unleash
nextjs-themes
Unleash the Power of React Server Components! Use multiple themes on your site with confidence, without losing any advantages of React Server Components.
npm install @unleash/nextjs
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
28 Stars
147 Commits
9 Forks
5 Watching
4 Branches
16 Contributors
Updated on 26 Nov 2024
TypeScript (98.94%)
JavaScript (1.06%)
Cumulative downloads
Total Downloads
Last day
-10.3%
8,165
Compared to previous day
Last week
5.4%
42,207
Compared to previous week
Last month
5.1%
179,029
Compared to previous month
Last year
351.3%
1,732,328
Compared to previous year
8
This package allows easy integration of Unleash feature flags in a Next.js application.
To install, simply run:
1npm install @unleash/nextjs 2# or 3yarn add @unleash/nextjs 4# or 5pnpm add @unleash/nextjs
There is an ./example
project that you can deploy to Vercel or edit in CodeSandbox.
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/api/frontend
.If using server-side (SSR, SSG, API), using getDefinitions()
and evaluateFlags()
, set:
UNLEASH_SERVER_API_URL
of you instance. URL should end with /api
UNLEASH_SERVER_API_TOKEN
server-side API client tokenPrefixable | 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.
This package is ready for server-side use with App Router.
Refer to ./example/README.md#App-router
for an implementation example.
1import { cookies } from "next/headers"; 2import { evaluateFlags, flagsClient, getDefinitions } from "@unleash/nextjs"; 3 4const getFlag = async () => { 5 const cookieStore = cookies(); 6 const sessionId = 7 cookieStore.get("unleash-session-id")?.value || 8 `${Math.floor(Math.random() * 1_000_000_000)}`; 9 10 const definitions = await getDefinitions({ 11 fetchOptions: { 12 next: { revalidate: 15 }, // Cache layer like Unleash Proxy! 13 }, 14 }); 15 16 const { toggles } = evaluateFlags(definitions, { 17 sessionId, 18 }); 19 const flags = flagsClient(toggles); 20 21 return flags.isEnabled("nextjs-example"); 22}; 23 24export default async function Page() { 25 const isEnabled = await getFlag(); 26 27 return ( 28 <p> 29 Feature flag is{" "} 30 <strong> 31 <code>{isEnabled ? "ENABLED" : "DISABLED"}</code> 32 </strong> 33 . 34 </p> 35 ); 36}
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.
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
.
1import type { AppProps } from "next/app"; 2import { FlagProvider } from "@unleash/nextjs/client"; 3 4export default function App({ Component, pageProps }: AppProps) { 5 return ( 6 <FlagProvider> 7 <Component {...pageProps} /> 8 </FlagProvider> 9 ); 10}
With <FlagProvider />
in place you can now use hooks like: useFlag
, useVariant
, or useFlagsStatus
to block rendering until flags are ready.
1import { useFlag } from "@unleash/nextjs/client"; 2 3const YourComponent = () => { 4 const isEnabled = useFlag("nextjs-example"); 5 6 return <>{isEnabled ? "ENABLED" : "DISABLED"}</>; 7};
Optionally, you can configure FlagProvider
with the config
prop. It will take priority over environment variables.
1<FlagProvider 2 config={{ 3 url: "http://localhost:4242/api/frontend", // replaces NEXT_PUBLIC_UNLEASH_FRONTEND_API_URL 4 clientKey: "<Frontend_API_token>", // replaces NEXT_PUBLIC_UNLEASH_FRONTEND_API_TOKEN 5 appName: "nextjs", // replaces NEXT_PUBLIC_UNLEASH_APP_NAME 6 7 refreshInterval: 15, // additional client configuration 8 // see https://github.com/Unleash/unleash-proxy-client-js#available-options 9 }} 10>
If you only plan to use Unleash client-side React SDK now also works with Next.js. Check documentation there for more examples.
With same access as in the client-side example above you can resolve Unleash feature flags when building static pages.
1import { 2 flagsClient, 3 getDefinitions, 4 evaluateFlags, 5 getFrontendFlags, 6 type IVariant, 7} from "@unleash/nextjs"; 8import type { GetStaticProps, NextPage } from "next"; 9 10type Data = { 11 isEnabled: boolean; 12 variant: IVariant; 13}; 14 15const ExamplePage: NextPage<Data> = ({ isEnabled, variant }) => ( 16 <> 17 Flag status: {isEnabled ? "ENABLED" : "DISABLED"} 18 <br /> 19 Variant: {variant.name} 20 </> 21); 22 23export const getStaticProps: GetStaticProps<Data> = async (_ctx) => { 24 /* Using server-side SDK: */ 25 const definitions = await getDefinitions(); 26 const context = {}; // optional, see https://docs.getunleash.io/reference/unleash-context 27 const { toggles } = evaluateFlags(definitions, context); 28 29 /* Or with the proxy/front-end API */ 30 // const { toggles } = await getFrontendFlags({ context }); 31 32 const flags = flagsClient(toggles); 33 34 return { 35 props: { 36 isEnabled: flags.isEnabled("nextjs-example"), 37 variant: flags.getVariant("nextjs-example"), 38 }, 39 }; 40}; 41 42export 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.
1import { 2 flagsClient, 3 evaluateFlags, 4 getDefinitions, 5 type IVariant, 6} from "@unleash/nextjs"; 7import type { GetServerSideProps, NextPage } from "next"; 8 9type Data = { 10 isEnabled: boolean; 11}; 12 13const ExamplePage: NextPage<Data> = ({ isEnabled }) => ( 14 <>Flag status: {isEnabled ? "ENABLED" : "DISABLED"}</> 15); 16 17export const getServerSideProps: GetServerSideProps<Data> = async (ctx) => { 18 const sessionId = 19 ctx.req.cookies["unleash-session-id"] || 20 `${Math.floor(Math.random() * 1_000_000_000)}`; 21 ctx.res.setHeader("set-cookie", `unleash-session-id=${sessionId}; path=/;`); 22 23 const context = { 24 sessionId, // needed for stickiness 25 // userId: "123" // etc 26 }; 27 28 const definitions = await getDefinitions(); // Uses UNLEASH_SERVER_API_URL 29 const { toggles } = evaluateFlags(definitions, context); 30 31 const flags = flagsClient(toggles); // instantiates a static (non-syncing) unleash-proxy-client 32 33 return { 34 props: { 35 isEnabled: flags.isEnabled("nextjs-example") 36 }, 37 }; 38}; 39 40export default ExamplePage;
You can bootstrap Unleash React SDK to have values loaded from the start. Initial value can be customized server-side.
1import App, { AppContext, type AppProps } from "next/app"; 2import { 3 FlagProvider, 4 getFrontendFlags, 5 type IMutableContext, 6 type IToggle, 7} from "@unleash/nextjs"; 8 9type Data = { 10 toggles: IToggle[]; 11 context: IMutableContext; 12}; 13 14export default function CustomApp({ 15 Component, 16 pageProps, 17 toggles, 18 context, 19}: AppProps & Data) { 20 return ( 21 <FlagProvider 22 config={{ 23 bootstrap: toggles, 24 context, 25 }} 26 > 27 <Component {...pageProps} /> 28 </FlagProvider> 29 ); 30} 31 32CustomApp.getInitialProps = async (ctx: AppContext) => { 33 const context = { 34 userId: "123", 35 }; 36 37 const { toggles } = await getFrontendFlags(); // use Unleash Proxy 38 39 return { 40 ...(await App.getInitialProps(ctx)), 41 bootstrap: toggles, 42 context, // pass context along so client can refetch correct values 43 }; 44};
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.
1const enabled = flags.isEnabled("nextjs-example"); 2 3await flags.sendMetrics();
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.
1import {evaluateFlags, flagsClient, getDefinitions,} from "@unleash/nextjs"; 2 3export default async function Page() { 4 const definitions = await getDefinitions({ 5 fetchOptions: { 6 next: { revalidate: 15 }, // Cache layer like Unleash Proxy! 7 }, 8 }); 9 const context = {}; 10 const { toggles } = evaluateFlags(definitions, context); 11 const flags = flagsClient(toggles); 12 13 const enabled = flags.isEnabled("nextjs-example"); 14 15 // await client.sendMetrics().catch(() => {}); // blocking metrics 16 flags.sendMetrics().catch(() => {}); // non-blocking metrics 17 18 return <>Flag status: {enabled ? "ENABLED" : "DISABLED"}</> 19}
1import { evaluateFlags, flagsClient, getDefinitions } from "@unleash/nextjs"; 2import {GetServerSideProps, NextPage} from "next"; 3 4type Data = { 5 isEnabled: boolean; 6}; 7 8export const getServerSideProps: GetServerSideProps<Data> = async () => { 9 const definitions = await getDefinitions({ 10 fetchOptions: { 11 next: { revalidate: 15 }, // Cache layer like Unleash Proxy! 12 }, 13 }); 14 const context = {}; 15 const { toggles } = evaluateFlags(definitions, context); 16 const flags = flagsClient(toggles); 17 18 const enabled = flags.isEnabled("nextjs-example"); 19 20 // await client.sendMetrics().catch(() => {}); // blocking metrics 21 flags.sendMetrics().catch(() => {}); // non-blocking metrics 22 23 return { 24 props: { isEnabled: enabled }, 25 }; 26}; 27 28const ExamplePage: NextPage<Data> = ({ isEnabled }) => ( 29 <>Flag status: {isEnabled ? "ENABLED" : "DISABLED"}</> 30); 31 32export default ExamplePage;
In middleware.ts
you can use event.waitUntil()
to reliably send metrics without delaying the response.
1export async function middleware(req: NextRequest, event: NextFetchEvent) {
2 // ...
3 const evaluated = evaluateFlags(definitions, context);
4 const flags = flagsClient(evaluated.toggles)
5 const isEnabled = flags.isEnabled("example-flag")
6
7 event.waitUntil(flags.sendMetrics())
8 // ...
9}
setInterval
support (e.g. long-running Node process or AWS lambda)If your Next application resolves flags only in SSR mode and setInterval
is supported then you may also consider using Node.js SDK instead, which is less taxing on metrics reporting.
Check this blog post for more information on short-running lambdas that still support setInterval
.
You can use unleash [action] [options]
in your package.json
scripts
section, or with:
1npx @unleash/nextjs
For the CLI to work, the following environment variables must be configured with appropriate values:
UNLEASH_SERVER_API_URL
UNLEASH_SERVER_API_TOKEN
The CLI will attempt to read environment values from any .env
files if they're present. You can also set the variables directly when invoking the interface, as in the CLI usage example.
get-definitions <outputFile.json>
Download feature flags definitions for bootstrapping (offline use) of server-side SDK.generate-types [options] <outputFile.ts>
Generate types and typed functions from feature flags defined in an Unleash instance.
It will also generate strictly typed versions of useFlag
, useVariant
, useFlags
and flagsClient
(unless --typesOnly
is used).
-t, --typesOnly
don't include typed versions of functions exported from @unleash/nextjs
(default: false)-b, --bootstrap <sourceFile.json>
load definitions from a file instead of fetching definitions - work offline-V
Output the version numberTry it now
1UNLEASH_SERVER_API_URL=https://app.unleash-hosted.com/demo/api \ 2UNLEASH_SERVER_API_TOKEN=test-server:default.8a090f30679be7254af997864d66b86e44dcfc5291916adff72a0fb5 \ 3npx @unleash/nextjs generate-types ./unleash.ts
No vulnerabilities found.
No security vulnerabilities found.