Guides
Next.js - App Router

Next.js Guide - App router

Modern web frameworks offer different rendering strategies to improve the user experience and performance of your web applications. This guide will show you how to configure FeaturesFlow in Next.js, server-side, client-side or a mix of the two.

Next.js App Router prioritizes server-side rendering by default. This means that your pages are rendered on the server-side and then sent to the client. This is a great way to improve the performance of your web application by reducing the time it takes to load the page.

This also leads to interesting considerations when it comes to feature flags. In this guide, we will show you how to use FeaturesFlow in Next.js, server-side, client-side or a mix of the two.

Server-side rendering

To use feature flags in a server rendered environment, you can fetch the feature flags from FeaturesFlow directly in your component.

Here's an example of how you can do this:

app/page.tsx
import { VariantA } from "@/components/VariantA";
import { VariantB } from "@/components/VariantB";
import { FeaturesFlowClient, FeaturesFlowConfig } from '@featuresflow/sdk-js';
 
export default async function ServerSide() {
 
    const ffConfig: FeaturesFlowConfig = {
        authenticationKey: 'YOUR_AUTHENTICATION_KEY',
        trafficType: 'session',
        identifier: 'YOUR_USER_ID',
    }
 
    const client = new FeaturesFlowClient()
 
    await client.init(ffConfig)
 
    const treatment = client.getFeatureToggle('demo-feature-toggle')
 
    return (
        <main className='flex h-screen w-screen justify-center items-center'>
            <div className='fixed top-0 left-0 px-4 py-2 bg-indigo-700 text-white rounded-br-md'>{treatment}</div>
 
            {treatment === 'VariantA' && <VariantA />}
 
            {treatment === 'VariantB' && <VariantB />}
        </main>
    )
}

This example shows how you can fetch the feature flags from FeaturesFlow directly in your component. We are using the FeaturesFlowClient class to fetch the feature flags. We then use the getFeatureToggle method to retrieve the treatment for the feature flag demo-feature-toggle.

This method has one limitation. Since server component can't use context, you would need to fetch the feature flags in separate components if you are using more than one of them. This can lead to multiple requests to FeaturesFlow, which can impact the performance of your application.

To avoid this, you can fetch the feature flags on the server-side and pass them to the client-side. This way, you can avoid fetching the feature flags on every request. See the section below for more information.

Server-side-to-client-side rendering

In most cases, you will want to use the treatment in more than one place within your React tree. To avoid prop drilling or fetching feature flags in multiple components, you can fetch them on the server-side and pass them to the client-side.

app/page.tsx
import { getFeatures, FeaturesFlowConfig } from '@featuresflow/sdk-base'
import { FeaturesFlowProvider } from '@featuresflow/sdk-react'
import React from 'react'
import { MyComponent } from "@/components/my-component";
 
const ffConfig: FeaturesFlowConfig = {
    authenticationKey: 'YOUR_AUTHENTICATION_KEY',
    trafficType: 'session',
    identifier: 'YOUR_USER_ID',
}
 
export default async function ServerSideToClientSide() {
    const res = await getFeatures(ffConfig)
 
    const treatments = res.status === 'success' ? res.features : {}
 
    return (
        <FeaturesFlowProvider config={{
          authenticationKey: 'YOUR_AUTHENTICATION_KEY',
          identifier: 'YOUR_USER_ID',
          options: {
            prefetchedFeatures: treatments
          }}}>
            <MyComponent />
        </FeaturesFlowProvider>
    )
}

In this example, we are fetching the feature flags from FeaturesFlow on the server-side using the getFeatures function. We then pass the treatments to the FeaturesFlowProvider through prefetchedFeatures param.

By doing that, you avoid fetching the feature flags on the client-side, which can improve the performance of your application.

Now, lets take a look on how can you retrieve the treatment in your component:

app/components/MyComponent.tsx
import React from 'react'
import { VariantA } from "@/components/VariantA";
import { VariantB } from "@/components/VariantB";
import { useFeatureToggle } from '@featuresflow/sdk-react';
 
export const MyComponent = () => {
    const treatment = useFeatureToggle('demo-feature-toggle')
 
 
    return (
        <>
            {treatment === 'VariantA' ?  <VariantA /> : <VariantB />}
        </>
    )
}

In the code snippets above, we are fetching the feature flags on the server-side and passing them to the client-side component. We then use the useFeatureToggle hook to retrieve the treatment for the feature flag demo-feature-toggle.

Dependency notice

The @featuresflow/sdk-react package is a wrapper around the @featuresflow/sdk-base package. Make sure to install both packages in your project. It won't increase your bundle size as the @featuresflow/sdk-react package is just a wrapper around the @featuresflow/sdk-base package. This is required to import the getFeatures function in the server-side code.

Client-side rendering

If you want to fetch the feature flags on the client-side, you can use the FeaturesFlowProvider component to fetch the feature flags and pass them to the children components.

app/page.tsx
'use client'
import { FeaturesFlowProvider } from '@featuresflow/sdk-react';
import { MyComponent } from "@/components/my-component";
 
const ffConfig= {
    authenticationKey: 'YOUR_AUTHENTICATION_KEY',
    identifier: 'YOUR_USER_ID',
}
 
export default function ClientSide() {
 
    return (
        <FeaturesFlowProvider config={ffConfig}>
            <MyComponent />
        </FeaturesFlowProvider>
    )
}

Then, you can use the useFeatureToggle hook to retrieve the treatment for your feature flag in the exact same way as in server-side-to-client-side rendering.

app/components/MyComponent.tsx
import React from 'react'
import { VariantA } from "@/components/VariantA";
import { VariantB } from "@/components/VariantB";
import { useFeatureToggle } from '@featuresflow/sdk-react';
 
export const MyComponent = () => {
    const treatment = useFeatureToggle('demo-feature-toggle')
 
 
    return (
        <>
            {treatment === 'VariantA' ?  <VariantA /> : <VariantB />}
        </>
    )
}

Get started with FeaturesFlow

Create a free account and start using FeaturesFlow today.