Next.js + FeatBit

Run stable browser-level experiments without requiring login

Anonymous browser IDs let you keep the same visitor in the same FeatBit bucket across refreshes, which is what controlled rollout and experimentation actually need.

Open chat CTA is hidden because the flag is currently OFF.
Live server snapshotconfigured
heroFlagKey = "homepage-hero-variant"
heroVariant = "experiment"
chatFlagKey = "homepage-show-chat-cta"
showChatCta = false
renderedOpenChatButton = false
user.key = "anon_missing_cookie"

One persistent connection

The Node SDK keeps one long-lived connection per server process instead of doing HTTP eval on every page load.

Local evaluation

After initialization, the actual variation lookup is local on the server, which removes the front-end wait you were concerned about.

SSR-first behavior

The page ships the chosen variation in the first HTML response, which avoids the common client-side flicker pattern.

Anonymous browser user

This demo now evaluates flags against a stable anonymous browser user instead of a hard-coded demo identity. As long as the visitor stays on the same browser profile, FeatBit will keep seeing the same user key.

user.key = "anon_missing_cookie"
user.name = "cookiebifgz"
source = "unknown"
ip = "216.73.216.147:52977"
country = "unknown"
region = "unknown"
rootUrl = "https://www.featbit.co"
deviceType = "desktop"
deviceVendor = "unknown"
deviceModel = "unknown"
browserName = "unknown"
browserVersion = "unknown"
osName = "unknown"
isBot = "false"

How these values are captured:

1. IP, country, region, and root URL are read from the incoming request on the server, not from browser-side SDK code.

2. Middleware normalizes them into request headers, then the Node SDK evaluation attaches them to the FeatBit user.

3. The anonymous browser key still stays stable, so percentage rollout and experiments remain sticky per browser.

Multivariate hero demo

This block is driven by the string flag homepage-hero-variant. Once you create it in FeatBit, the same anonymous browser should stay in the same variant bucket across refreshes.

control

Server-side feature flags for a stable Next.js first render

Use FeatBit Node SDK on the server to evaluate once per request and send the chosen UI in the first HTML response.

cost

Cut front-end flag latency by moving evaluation to the server

This variant emphasizes the operational benefit: fewer browser-side waits, fewer moving pieces, and cleaner SSR behavior.

experiment

Run stable browser-level experiments without requiring login

Anonymous browser IDs let you keep the same visitor in the same FeatBit bucket across refreshes, which is what controlled rollout and experimentation actually need.

Recommended env vars

FEATBIT_SDK_KEY=your-server-side-environment-secret

FEATBIT_STREAMING_URI=wss://app-eval.featbit.co

FEATBIT_EVENTS_URI=https://app-eval.featbit.co

  • Keep the secret only on the server. Do not expose it via public env vars.
  • Use a singleton client so hot reload and server restarts do not create a new connection on every render.
  • Render the first page with server-evaluated flags, then pass only the result to client components if needed.

Minimal App Router usage

import { getFeatBitFlags } from "@/lib/featbit/server";

export default async function Page() {
  const { flags } = await getFeatBitFlags();

  return <pre>{JSON.stringify(flags, null, 2)}</pre>;
}

Flag-controlled result

This panel is driven by the boolean flag homepage-show-chat-cta. With your current FeatBit setup, the value returned on the server is false.

Chat CTA is OFF, so the extra call-to-action button stays hidden.