@vercel/flags

The @vercel/flags package provides the core functionality for integrating with Vercel.

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 '@vercel/flags';
reportValue('summer-sale', true);

encrypt

A method for encrypting data (Flag definitions, overrides, and values). Returns a Promise.

ParameterTypeDescription
dataObjectData to be encrypted
secret (Optional)stringThe secret being used to encrypt. Defaults to process.env.FLAGS_SECRET

Here is an example of encrypting flag values to be used by the Vercel Toolbar.

app/page.tsx
import { encrypt } from '@vercel/flags';
import { FlagValues, type FlagValuesType } from '@vercel/flags/react';
async function ConfidentialFlagValues({ values }: { values: FlagValuesType }) {
const encryptedFlagValues = await encrypt(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>
);
}

decrypt

A method for decrypting data. Returns a Promise.

ParameterTypeDescription
encryptedDatastringData to be decrypted
secret (Optional)stringThe secret being used to encrypt data. Defaults to process.env.FLAGS_SECRET

The decrypt method's primary use case is decrypting the data stored inside the vercel-flag-overrides cookie. It's also used by the Vercel Toolbar to handle your feature flag data.

app/get-flags.ts
import { FlagOverridesType, decrypt } from '@vercel/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 decrypt<FlagOverridesType>(overrideCookie)
: {};
const flags = {
exampleFlag: overrides?.exampleFlag ?? false,
};
return flags;
}

verifyAccess

A method for verifying whether a request to your application's flags endpoint was made by the Vercel Toolbar. You can use verifyAccess to keep your endpoint private. Returns a Promise with a true or false value.

ParameterTypeDescription
authHeader.stringAuthorization header to check
secret (Optional)stringThe secret being used to encrypt data. Defaults to process.env.FLAGS_SECRET
app/.well-known/vercel/flags/route.ts
import { NextResponse, type NextRequest } from "next/server";
import { verifyAccess, type ApiData } from "@vercel/flags";
export async function GET(request: NextRequest) {
const access = await verifyAccess(request.headers.get('Authorization'));
if (!access) return NextResponse.json(null, { status: 401 });
const apiData: ApiData = /* ... */
return NextResponse.json<ApiData>(apiData);
}

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 ApiData, verifyAccess } from "@vercel/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 apiData: ApiData = { ... };
return response.status(200).json(apiData);
}
next.config.js
module.exports = {
async rewrites() {
return [
{
source: '/.well-known/vercel/flags',
destination: '/api/vercel/flags',
},
];
},
};

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 '@vercel/flags';
safeJsonStringify({ markup: '<html></html>' });
// '{"markup":"\\u003chtml>\\u003c/html>"}'