How and When to Use Feature Flags in NextJS

Feature flags are a powerful tool in any developer’s toolkit — they let you turn features on or off (usually without deploying new code too). Whether you’re running A/B tests, hiding unfinished features, or rolling things out gradually, feature flags help you move fast without putting your users at risk.

In our current Next.js project, our team needed feature flags — but we needed them fast. Here’s a quick overview of the options available in Next.js, and why we decided to start simple with environment variables.

Feature Flag Options in Next.js

Depending on your needs, there are a few different ways to implement feature flags in a Next.js app:

1. Environment Variables

The fastest and easiest method. You define flags in .env files and reference them in your code. These are available at build time and (if prefixed with NEXT_PUBLIC_) can be used on the client too.

NEXT_PUBLIC_SHOW_SIDEBAR=true
{process.env.NEXT_PUBLIC_SHOW_SIDEBAR === 'true' < Sidebar /> }

Pros: Dead simple, no extra dependencies
Cons: Requires redeploy to change flags

2. API-Driven Flags

Fetch flags at runtime from an internal config endpoint or third-party service. You can load them in getServerSideProps or using a hook like SWR.


// pages/api/flags.js
export default function handler(req, res) {
  const flags = {
    enableSidebar: true,
    showBetaUI: false,
  };

  res.status(200).json(flags);

// client side consumption
import useSWR from 'swr';

const fetcher = url => fetch(url).then(res => res.json());

export default function HomePage() {
  const { data: flags, isLoading } = useSWR('/api/flags', fetcher);
  if (isLoading) return
Loading…

; return (

< h1>Welcome{flags.enableSidebar && < Sidebar />}

); }

Pros: Dynamic and flexible
Cons: Requires more setup and server/client coordination

3. Middleware-Based Flags

Use Next.js Middleware to set or evaluate flags at the edge, based on cookies, geolocation, or headers.


import { NextResponse } from 'next/server';

export function middleware(request) {
  const response = NextResponse.next();

  // Example: Enable beta UI for users with "beta" cookie
  const betaUser = request.cookies.get('beta')?.value === 'true';

  // Set a request header or cookie for downstream use
  response.headers.set('x-feature-beta-ui', betaUser ? 'enabled' : 'disabled');

  return response;
}

Pros: Great for A/B testing, personalization
Cons: Requires more infrastructure and care with caching

4. Third-Party Flag Services

Tools like LaunchDarkly, Flagsmith, and Unleash offer full-featured flag platforms — targeting, analytics, gradual rollouts, etc.

Pros: Powerful and scalable
Cons: Often overkill for early-stage needs, and adds cost

Why We Chose Environment Variables

For this project, our needs were modest. We wanted to hide a few features behind flags during development and selectively enable them in production.

We chose environment variables because:
– They were quick to set up.
– They required no new dependencies.
– Our flags didn’t need to change on the fly.

It was as simple as defining NEXT_PUBLIC_ variables in .env.local and checking them in the UI. We used them to gate features like new components, experimental flows, and integrations still in testing. Once features were thoroughly tested, we submit a PR to toggle them for Staging and/or Production.

This approach gave us just enough flexibility to move forward confidently, without introducing additional complexity.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *