Implementing Feature Flags in a Next.js Application

Implementing Feature Flags in a Next.js Application

Our job as developers often involves releasing new features regularly. However, how can we ensure that these features work properly in production before safely releasing them to all users? It's easy, by feature flagging!

What is Feature Flagging?

Many companies struggle to roll out new features and functionalities in an incremental way. Feature flagging is a mechanism used to control access to certain features with simple switches called feature flags, feature toggles or feature switches.

Through feature flagging, anyone can safely test code in production, perform canary releases, conduct A/B testing, and many other unique uses. You can deliver different content and functionalities to targeted users through user segmentation based on a feature flag’s value and its associated config rules.

What Exactly are Feature Flags?

illustration of feature flags in action

Feature flags are conceptually based on being able to encapsulate sections of your code into conditional statements that can be switched on and off depending on your needs.

Similarly to an if/else statement, these flags return true/false boolean values based on the state of the feature flags (whether they are toggled on or off) and are implemented directly inside your source code to check these external conditions before executing the code.

Feature Flag Use Case in a Next.js Application

Consider this scenario: Suppose we implemented a new feature in a Next.js application that allowed us to generate random user profiles with every page load or reload, and we wanted to roll this out to our user base.

As you may have guessed already, wrapping this feature in a feature flag would give us the perfect control needed to plan a feature release to our users either through incremental roll-out via user segmentation or performing an all-out release.

We will examine how we can accomplish this by creating a Next.js application that incorporates the aforementioned feature with a feature flag in a step by step process.

Requirements:

  • Basic knowledge of Next.js.
  • You’ve local installation of Node and NPM.

Step 1: Create a New Feature Flag Using a Feature Flagging Service

Rather than going through the hassle of building and managing an actual feature flag from scratch, I’ll be using ConfigCat – a company that offers feature flags as a service – to create and remotely manage our feature flag from its dashboard.

So quickly jump to ConfigCat and create a free account, then:

  1. Navigate to your dashboard.
  2. Click the ‘Add feature flag’ option and provide the required details about the flag.
  3. Copy the ConfigCat SDK Key (this will be needed to enable us to connect our Next.js app to our feature flag). A screencast illustrating how to create a feature flag and copying the SDK key

Step 2: Configure and Set Targeting Rules for the Feature Flag

As a feature flag management service, ConfigCat provides multiple ways to target your users with feature flags to achieve a controlled feature release. This can be done by targeting a certain percentage of your traffic allocation or through user segmentation where you can specify the target audience for your feature release based on a list of predefined (or custom) shared attributes such as location, gender, age, etc.

To keep things simple, I'll be using the default settings – which is to target all users.

random user feature flag toggle

Step 3: Creating the Base Version of the Next.js App

Now that we have our feature flag ready, It’s time for us to create our Next.js application. We’ll start by running create-next-app in the command line to quickly bootstrap a Next.js application for us.

    npx create-next-app

Afterwards, we run the following command to launch our dev environment and have our starter template demo page ready:

    npm run dev

demo of Next.js app

Step 4: Create Random User Generator Feature in Next.js Application

There are two ways that Next.js pre-renders web pages: Static Generation and Server-side Rendering. In Static Generation, the pages are generated at build time while in Server-side rendering, the page is generated on the server on each request before being sent to the client.

We will be taking the Server-side rendering route because we will be using a third party Random User API to get new random user data on each user request (whenever the page is loaded/reloaded).

Let’s get to it.

I’ll start by emptying the root index.js file responsible for the home page of our demo application and then creating an export getServerSideProps function that would be responsible for making requests on the server before the page is generated.

    // This runs on the server on each request
    export async function getServerSideProps() {
      // Fetch random user data from external API
      const res = await fetch("https://randomuser.me/api/");
      const data = await res.json();

      // Return data to page via props
      return { props: { data: data.results } };
    }

This random user API returns an array containing an object of randomly generated user details:

random user api response

After making the request on the server, the next step is to make use of the data in our component’s template and render the required user details.

    // Page Component
    export default function Home({ data }) {
      // Extract the required user details
      const firstName = data[0].name.first;
      const lastName = data[0].name.last;
      const image = data[0].picture.large;
      const gender = data[0].gender;
      const location = data[0].location.country;

      // Generated page Template
      return (
        <div className='card'>
          <img src={image} class={gender} />
          <h2>{`${firstName} ${lastName}`}</h2>
          <p><span>Gender: </span> {gender}</p>
          <p><span>Location: </span>{location}</p>
        </div>
      );
    }

With that, we have a Next.js app that generates random user details on each page load/reload:

random user generator page

That’s pretty much it, we now have a fully working random user generator feature in our Next.js application.

Step 5: Connecting the Next.js Application to ConfigCat and Integrating the Feature Flag

Now that we have our feature ready, it’s time to connect our Next.js application to our feature flagging service provider, before proceeding to integrate the random user generator feature with our feature flag.

Since we intend to use ConfigCat, I will start by installing their JavaScript (SSR) SDK via NPM - this is required to connect our application to ConfigCat:

    npm i configcat-js-ssr

Afterwards, I’ll import the installed package into our root index.js component and refactor our getServerSideProps function by initializing the package using the SDK key copied from the dashboard (i.e. connect our application to ConfigCat using the SDK key):

    import * as configcat from "configcat-js-ssr";

    // This runs on the server on each request
    export async function getServerSideProps() {
      // Initialize ConfigCatClient with your SDK Key:
      const configCatClient = configcat.createClient(
        "fK7ZCApWbkaDu14njPKZQw/vBw-jxALN0eiWNilfwboGA");

      // Check the state of the feature flag
      const randomUserFlag = await configCatClient.getValueAsync(
        "randomuserflag", false);

      // Fetch random user data from external API
      const res = await fetch("https://randomuser.me/api/");
      const data = await res.json();

      // Return flag's state and dat to page via props
      return { props: { randomUserFlag, data: data.results } };
    }

The next step is to refactor the template to only render the random profile card if the feature flag is toggled on, and to otherwise render a different message:

    // Page Component
    export default function Home({ data, randomUserFlag }) {
      // Extract the required user details
      const firstName = data[0].name.first;
      const lastName = data[0].name.last;
      const image = data[0].picture.large;
      const gender = data[0].gender;
      const location = data[0].location.country;

      // Page Template
      return (
        <>
          {randomUserFlag && (
            <div className='card'>
              <img src={image} class={gender} />
              <h2>{`${firstName} ${lastName}`}</h2>
              <p><span>Gender: </span> {gender}</p>
              <p><span>Location: </span>{location}</p>
            </div>
          )}
          {!randomUserFlag && <p>Feature has been toggled off</p>}
        </>
      );
    }

With that final touch, our feature flag now has control over our random profile card. If we toggle on the feature flag:

feature flag toggled on

Our users would have access to the random profile card generator: feature enabled

But when the feature flag is toggled off:

feature flag toggled off

Our users have no access to the feature:

feature disabled

Final thoughts

We have seen how feature flagging takes a simple concept - choosing between different code paths at runtime - to help teams introduce features in a controlled manner while in production.

Through feature flagging, you can ship code more frequently, test in production, perform canary deployment and master feature releases to deliver high-quality software while also reducing some of the risks that come with continuous deployment.

You may find the following links helpful if you'd like to explore further:

More information about ConfigCat can be found on its Facebook, Twitter and LinkedIn pages.