GitHub

flags

The `flags` package provides the core functionality for integrating with Vercel.

verifyAccess

A method for verifying access to your flags endpoint based on encrypted tokens (JWEs) generated by the SDK functions documented below. You can use verifyAccess to keep your endpoint private, but allow the Vercel Toolbar to access it. Returns a Promise with a true or false value.

If you are using Next.js App Router you should use createFlagsDiscoveryEndpoint instead, which will create the full route handler.

ParameterTypeDescription
authorizationstringAuthorization token to verify
app/.well-known/vercel/flags/route.ts
import { NextResponse, type NextRequest } from "next/server";
import { verifyAccess, version, type ProviderData, type ApiData } from "flags";
 
export async function GET(request: NextRequest) {
  const access = await verifyAccess(request.headers.get('Authorization'));
  if (!access) return NextResponse.json(null, { status: 401 });
 
  const providerData: ProviderData = /* ... */
 
  return NextResponse.json<ApiData>(providerData, {
    headers: { 'x-flags-sdk-version': version },
  });
}

If you are using the Pages router, you will need to add the following to your next.config.js. This is because the Pages router can't specify API routes outside of the api folder. This means you need a rewrite.

pages/api/vercel/flags.ts
import type { NextApiRequest, NextApiResponse } from "next";
import { type ProviderData, verifyAccess } from "flags";
 
export async function handler(request: NextApiRequest, response: NextApiResponse) {
  const access = await verifyAccess(request.headers.get('Authorization'));
  if (!access) return response.json(null, { status: 401 });
 
  const providerData: ProviderData = { ... };
 
  return response.status(200).json(providerData);
}
next.config.js
module.exports = {
  async rewrites() {
    return [
      {
        source: '/.well-known/vercel/flags',
        destination: '/api/vercel/flags',
      },
    ];
  },
};

mergeProviderData

Merges provider data from multiple sources. Extends the feature flags defined in code with metadata from your feature flag provider, for use with the Flags Explorer.

ParameterTypeDescription
data(ProviderData | Promise<ProviderData>)[]A list of provider data objects to merge.
app/.well-known/vercel/flags/route.ts
import { getProviderData, createFlagsDiscoveryEndpoint } from 'flags/next';
import { getProviderData as getStatsigProviderData } from '@flags-sdk/statsig';
import { mergeProviderData } from 'flags';
import * as flags from '../../../../flags';
 
export const GET = createFlagsDiscoveryEndpoint(async (request) => {
  return mergeProviderData([
    getProviderData(flags),
    getStatsigProviderData({
      consoleApiKey: process.env.STATSIG_CONSOLE_API_KEY,
      projectId: process.env.STATSIG_PROJECT_ID,
    }),
  ]);
});

reportValue

Reports the value of a feature flag to Vercel so it can show up in Runtime Logs and be used with Web Analytics custom server-side events. Returns undefined.

ParameterTypeDescription
keystringKey of the feature flag
valueanyValue of the feature flag
import { reportValue } from 'flags';
 
reportValue('summer-sale', true);

Encryption and Decryption Functions

The flags package provides multiple purpose-specific encryption and decryption functions for different types of flag data. These functions add purpose claims to prevent misuse between different data types.

encryptFlagValues

Encrypts flag values data with a purpose claim. Returns a Promise.

ParameterTypeDescription
flagValuesFlagValuesTypeFlag values to be encrypted
secret (Optional)stringThe secret being used to encrypt. Defaults to process.env.FLAGS_SECRET
expirationTime (Optional)string | number | DateWhen the encrypted data should expire. Defaults to '1y' (1 year)
app/page.tsx
import { encryptFlagValues, type FlagValuesType } from 'flags';
import { FlagValues } from 'flags/react';
 
async function ConfidentialFlagValues({ values }: { values: FlagValuesType }) {
  const encryptedFlagValues = await encryptFlagValues(values);
  return <FlagValues values={encryptedFlagValues} />;
}
 
export function Page() {
  const values = { exampleFlag: true };
  return (
    <div>
      {/* Some other content */}
      <Suspense fallback={null}>
        <ConfidentialFlagValues values={values} />
      </Suspense>
    </div>
  );
}

decryptFlagValues

Decrypts flag values data, ensuring the proper purpose claim. Returns a Promise.

ParameterTypeDescription
encryptedDatastringEncrypted flag values to be decrypted
secret (Optional)stringThe secret being used to decrypt data. Defaults to process.env.FLAGS_SECRET

encryptFlagDefinitions

Encrypts flag definitions data with a purpose claim. Returns a Promise.

ParameterTypeDescription
flagDefinitionsFlagDefinitionsTypeFlag definitions to be encrypted
secret (Optional)stringThe secret being used to encrypt. Defaults to process.env.FLAGS_SECRET
expirationTime (Optional)string | number | DateWhen the encrypted data should expire. Defaults to '1y' (1 year)

decryptFlagDefinitions

Decrypts flag definitions data, ensuring the proper purpose claim. Returns a Promise.

ParameterTypeDescription
encryptedDatastringEncrypted flag definitions to be decrypted
secret (Optional)stringThe secret being used to decrypt data. Defaults to process.env.FLAGS_SECRET

encryptOverrides

Encrypts flag overrides data with a purpose claim. Returns a Promise.

ParameterTypeDescription
overridesFlagOverridesTypeFlag overrides to be encrypted
secret (Optional)stringThe secret being used to encrypt. Defaults to process.env.FLAGS_SECRET
expirationTime (Optional)string | number | DateWhen the encrypted data should expire. Defaults to '1y' (1 year)

decryptOverrides

Decrypts flag overrides data, ensuring the proper purpose claim. Returns a Promise.

ParameterTypeDescription
encryptedDatastringEncrypted flag overrides to be decrypted
secret (Optional)stringThe secret being used to decrypt data. Defaults to process.env.FLAGS_SECRET

The primary use case for decryptOverrides is decrypting data stored inside the vercel-flag-overrides cookie.

app/get-flags.ts
import { FlagOverridesType, decryptOverrides } from 'flags';
import { type NextRequest } from 'next/server';
import { cookies } from 'next/headers';
 
async function getFlags(request: NextRequest) {
  const overrideCookie = cookies().get('vercel-flag-overrides')?.value;
  const overrides = overrideCookie
    ? await decryptOverrides(overrideCookie)
    : {};
 
  const flags = {
    exampleFlag: overrides?.exampleFlag ?? false,
  };
 
  return flags;
}

verifyAccessProof

Compared to verifyAccess which is used commonly to keep your endpoint private, verifyAccessProof may rarely be needed for advanced use cases.

Verifies that an access proof token is valid. Returns a Promise with a true or false value.

ParameterTypeDescription
encryptedDatastringEncrypted access proof token to verify
secret (Optional)stringThe secret used for decryption. Defaults to process.env.FLAGS_SECRET
app/verify-access-proof.ts
import { verifyAccessProof } from 'flags';
 
// Example of verifying an access proof token
const isValid = await verifyAccessProof(tokenFromRequest);
if (isValid) {
  // Handle valid token
}

safeJsonStringify

A safe version of JSON.stringify that escapes the resulting output to prevent XSS attacks. Returns string.

ParameterTypeDescription
valueanyA valid JSON object to convert
replacer (Optional)function | ArrayA replacer function or Array
space (Optional)string | numberSpecifies the spacing in the output
import { safeJsonStringify } from 'flags';
 
safeJsonStringify({ markup: '<html></html>' });
// '{"markup":"\\u003chtml>\\u003c/html>"}'