Enabling Feature Flags in NextJS
Published: 2023-09-05 14:21:50

**Continuous delivery** is a software development practice where code changes are automatically built, tested, and prepared for release to production on a frequent basis. The goal is to make sure the software can be released at any time by keeping it in a releasable state.

**Feature toggles**, also known as **feature flags**, are an important technique that helps enable continuous delivery. A feature toggle allows a portion of code to be turned on or off without having to redeploy the application. This allows developers to merge code for an unfinished feature into the main codebase without impacting the production environment or users.

Here are some key reasons why feature toggles are important for continuous delivery:

- **Enable trunk-based development** - Rather than creating long-lived feature branches, developers can work on mainline and use toggles to 'hide' unfinished features. This avoids merge issues down the road.

- **Decouple deployment from release** - With toggles, you can deploy code frequently but control when partially completed features are exposed and released. Toggles decouple deployment from official release.

- **Reduce risk** - If issues come up after a deployment, you can simply toggle off a problematic feature without having to roll back the deployment. This reduces the risk and overhead of frequent deployments.

- **Facilitate testing** - Toggles allow you to dynamically turn features on and off during testing to verify both new and legacy code paths. No need to redeploy to test different scenarios.

- **Simplify rollbacks** - If a feature needs to be rolled back after release, you can quickly toggle the feature off rather than having to redeploy an older version.

By incorporating feature toggles into the continuous delivery process, teams can develop, test, and deploy software more frequently and with lower risk. Toggles help facilitate the flexibility and safety needed to release often.

Vercel provides 3 different options for implementing feature flags with Next.js: **Environment Variables**, **Edge Config**, and **Key Value Store**. Environment Variables allow you to toggle features on or off for different deployments. Edge Config enables low-latency reading of feature flags at the edge. And Key Value Store gives you a fast, durable Redis database to store and retrieve feature flag data. Each option has tradeoffs between flexibility, performance, and complexity that teams should evaluate when deciding on their feature flagging approach.

**NextJS Environment Variables**

Feature flags can be loaded into Next.js code as environment variables. For frontend code like React components, the variables need to be prefixed with NEXT_PUBLIC_ so they are exposed to the client side. For example:

```
// Component.jsx

export default function Component() {
  if(process.env.NEXT_PUBLIC_MY_FLAG) {
    return <p>Flag enabled!</p> 
  }

  return null;
}
```

For Serverless Functions, environment variables can be used without the NEXT_PUBLIC_ prefix. However, a downside is environment variables require a redeploy for changes to take effect, breaking continous delivery principles. For example:

```
// api/example.js 

export default async function handler(req, res) {
  if(process.env.MY_FLAG) {
    console.log('Flag enabled!');
  }
  
  // ...
}
```

Environment Variables can be used for feature flags in Next.js but require redeploys and some special handling between client and server side.

**NextJS Edge Config**

Next.js Edge Config provides a powerful way to implement feature flags without requiring redeploys. For example, you can use Edge Config with middleware routes to toggle page-level features. The middleware checks the config and routes to the appropriate page based on the flag:

```
// middleware.js

export default async function middleware(req) {
  const { featureFlags } = useEdgeConfig();

  if(featureFlags.newPageEnabled) {
    return NextResponse.rewrite('/new-page'); 
  }

  return NextResponse.next();
}
```

You can also use Edge Config in serverless functions and React components to toggle code paths. The config is fetched and logic changes based on flag values, no redeploy required:

```
// api/user.js

export default async function handler(req, res) {
  const { featureFlags } = useEdgeConfig();
  
  if(featureFlags.newUserFlow) {
    // new user flow
  } else {
    // old user flow
  }

  // ...
}
```

Edge Config provides a way to manage feature flags across Next.js without redeploys. Middleware and functions can check the config to route pages or enable/disable code paths. 

**NextJS KV Store**
Vercel's KV store is useful for implementing A/B testing by dynamically toggling features for a percentage of users. For example, you can use KV to show a new page to 25% of traffic for A/B testing. In Next.js middleware, on each request you can check the KV store to determine whether the user should see the new page based on the desired split percentage. The KV store enables maintaining state about user visits and toggling the feature on and off programmatically. This is valuable for A/B testing since you can specifically target the new experience to a portion of users (e.g. 10%, 25%) and analyze metrics versus a control group. Using KV allows implementing granular targeting and experimentation without needing an external A/B testing service.

```
// middleware.js 

export default async function middleware(req) {

  // Read visit count from KV
  const visits = await kv.get('visits');
  const count = visits ? visits.count : 0;

  // Update visit count in KV
  await kv.put('visits', {count: count + 1});

  // Show new page every 4 visits
  if(count % 4 === 0) { 
    return NextResponse.rewrite('/new-page');
  }

  return NextResponse.next(); 

}
```

In summary, feature toggles enabled by Vercel's Environment Variables, Edge Config, and Key Value Store provide Next.js developers powerful options to implement safe, continuous delivery. Each approach has tradeoffs to evaluate when deciding how to best implement feature flags for specific needs. Thank you for reading - I welcome any feedback or suggestions you may have on feature flagging with Next.js.