Reference
7 min read

Toolbar Flags Reference

In-depth reference for configuring Vercel Toolbar's feature flag support
Table of Contents

Feature flags are available in Beta on all plans

Before supporting feature flag overrides, familiarise yourself with feature flag concepts.

This secret gates access to the Flags API Endpoint, and optionally for signing and encrypting feature flag overrides set by Vercel Toolbar. Use verifyAccess to ensure the request is authenticated in your Flags API endpoint.

The FLAGS_SECRET value must have a specific length (32 random bytes encoded in base64) to work as an encryption key. You can create one using node:

node -e "console.log(crypto.randomBytes(32).toString('base64url'))"

In your local environment, pull your environment variables with vercel env pull to make them available to your project.

Adding the environment variable locally is not enough. Vercel Toolbar reads it from your project settings in the Vercel dashboard.

If you have set the FLAGS_SECRET environment variable on your project, Vercel Toolbar will query the /.well-known/vercel/flags endpoint to load your application's feature flag definitions and configuration.

A basic endpoint should call verifyAccess to ensure the request to load flags originates from Vercel Toolbar. This will check the Authorization header Vercel Toolbar sends. This header contains proof that whoever made this request has access to FLAGS_SECRET, but the secret itself is not sent over the network. Return status code 401 and no response body when the verifyAccess check fails.

When the verifyAccess check was successful you can return the feature flag definitions and other configuration as JSON.

Next.js (/app)
Next.js (/pages)
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 });
 
  return NextResponse.json<ApiData>({
    definitions: {
      newFeature: {
        description: 'Controls whether the new feature is visible',
        origin: 'https://example.com/#new-feature',
        options: [
          { value: false, label: 'Off' },
          { value: true, label: 'On' },
        ],
      },
    },
  });
}

The JSON response must have the following shape

type ApiData = {
  definitions: Record<
    string,
    {
      description?: string;
      origin?: string;
      options?: { value: any; label?: string }[];
    }
  >;
  hints?: { key: string; text: string }[];
  overrideEncryptionMode?: 'plaintext' | 'encrypted';
};

These are your application's feature flags. You can return the following data for each definition:

  • description (optional): A description of what this feature flag is for.
  • origin (optional): The URL where feature flag is managed. This usually points to the flag details page in your feature flag provider.
  • options (optional): An array of { value: any, label?: string }. These options will be available as overrides in Vercel Toolbar.

You can optionally tell Vercel Toolbar about the actual value flags resolved to. The Flags API Endpoint can not return this as the value might differ for each request. See Flag values instead.

In some cases you might need to fetch your feature flag definitions from your feature flag provider before you can return them from the Flags API Endpoint.

In case this request fails you can use hints. Any hints returned will show up in the UI.

This is useful when you are fetching your feature flags from multiple sources. In case one request fails you might still want to show the remaining flags on a best effort basis, while also displaying a hint that fetching a specific source failed. You can return definitions and hints simultaneously to do so.

Whenever you create an override Vercel Toolbar will set a cookie called vercel-flag-overrides.

The overrideEncryptionMode setting controls the value of the cookie:

  • plaintext: The cookie will contain the overrides as plain JSON. Be careful not to trust those overrides as users can manipulate the value easily.
  • encrypted: Vercel Toolbar will encrypt overrides using the FLAGS_SECRET before storing them in the cookie. This prevents manipulation, but requries decrypting them on your end before usage.

We highly recommend using encrypted mode as it protects against manipulation.

Vercel Toolbar uses a MutationObserver to find all script tags with data-flag-values and data-flag-definitions attributes. Any changes to content get detected by the toolbar.

Your Flags API Endpoint should return information about your application's feature flags like their key, description, origin, and available options.

However the Flags API Endpoint can not return the value a flag evaluated to, since this value might depend on the request which rendered the page initially.

The requested page can embed script tags to communicate the value of each flag used to render it.

If you are using React or Next.js, use the FlagValues component.

If you are using another framework or no framework at all you can render these script tags manually. The expected shape is:

type FlagValues = Record<string, any>;

Example communicating feature flag values through the DOM:

<script type="application/json" data-flag-definitions>
  {
    "showBanner": true,
    "showAds": false,
    "pricing": 5
  }
</script>

Using JSON.stringify within script tags leads to XSS vulnerabilities. Use safeJsonStringify exported by @vercel/flags to stringify safely.

Vercel Toolbar will combine these values with the definitions returned through the Flags API Endpoint.

We strongly recommend communicating your feature flag definitions through the Flags API Endpoint.

In rare cases it can be useful to communicate them through the HTML response instead. Vercel Toolbar will pick up any script tags included in the DOM which have a data-flag-definitions attribute.

If you are using React or Next.js, use the FlagsDefinitions component. If you are using another framework or no framework at all you can render these script tags manually. The expected shape is:

type FlagDefinitionsType = Record<
  string,
  {
    options?: {
      value: any;
      label?: string;
    }[];
    origin?: string;
    description?: string;
  }
>;

This example shows how to communicate a feature flag definition through the DOM:

<script type="application/json" data-flag-definitions>
  {
    "showBanner": {
      "description": "Shows or hide the banner",
      "origin": "https://example.com/showBanner",
      "options": [
        { "value": false, "label": "Hide" },
        { "value": true, "label": "Show" }
      ]
    }
  }
</script>

You can also encrypt the definitions before emitting them to prevent leaking your feature flags through the DOM.

import { safeJsonStringify } from '@vercel/flags';
 
<script type="application/json" data-flag-definitions>
  ${safeJsonStringify(definitions)}
</script>;

Using JSON.stringify within script tags leads to XSS vulnerabilities. Use safeJsonStringify exported by @vercel/flags to stringify safely.

Vercel Toolbar sets a cookie called vercel-flag-overrides whenever you apply overrides.

Depending on the overrideEncryptionMode setting, the cookie value will either be plain JSON or encrypted JSON.

Read this cookie in your applications to make your application respect the overrides set by Vercel Toolbar.

Any overrides you apply from Vercel Toolbar usually apply to your browser session only. However, you can recommend overrides to team members by either:

This workflow is great when you start working on a new feature in a branch, as the recommended overrides will travel with the branch from local development through to the preview deployment.

  1. First configure the overrides you would like to share as usual
  2. Then, instead of selecting Apply, select the chevron next to the Apply button to reveal further options
  3. Choose Apply and save overrides as recommendation to recommend these overrides to any team member visiting your branch locally or on a preview deployment

When a team member visits that branch they will get a notification suggesting to apply the overrides you recommended.

This workflow is great when you want to share once-off overrides with team members to reproduce a bug under certain conditions or to share a new feature.

  1. First configure the overrides you would like to share as usual
  2. Then, instead of selecting Apply, select the chevron next to the Apply button to reveal further options
  3. Choose Apply and copy link with overrides to copy a link to the page you are on, along with a query parameter containing your overrides.

You can send this link to team members. When they visit the link they will get a notification suggesting to apply the overrides you shared.

Last updated on May 23, 2024