Next.js 13+
This guide explains you how to implement Flagship with nextJS 13+
Next.js is a full-stack framework for building web applications using React components. With Next.js, you have different options for rendering your app's content. Each rendering option may require a different approach for successful Flagship integration.
Component-level rendering
With the release of React 18, we now have the ability to perform component-level rendering on both the client and server-side.
Client component: This type of component can only be rendered on the browser side. This may be due to a specific requirement or because it uses State and Lifecycle Effects, adds interactivity and event listeners, uses browser-only APIs, or uses custom hooks that depend on state, effects, or browser-only APIs.
Server component: This type of component is rendered by React on the server-side and then streamed to the browser.
Rendering in Next.js 13+
With Next.js, you have two options for rendering content, depending on your needs. All these rendering options can be used at the same time in the same application or even in the same page.
Here are rendering options:
Static Rendering: Your components can be pre-rendered at build time then stored for reuse on subsequent requests
Server and Client Components are rendered differently during Static Rendering:
Client Components have their HTML and JSON pre-rendered and cached on the server. The cached result is then sent to the client for hydration. Server Components are rendered on the server by React, and their payload is used to generate HTML. The same rendered payload is also used to hydrate the components on the client, resulting in no JavaScript needed on the client.
https://nextjs.org/docs/app/building-your-application/rendering#static-rendering
Dynamic rendering: Your Components are rendered on the server at request time and no result cache is done.
Flagship implementation
To successfully implement Flagship in a Next.js 13+ application, follow these steps:
Use
FlagshipProviderSSR
in server components (like layouts or pages)Configure your cache revalidation settings (optional)
Use the React SDK hooks in client components
Access flags in server components
Send analytics hits from both client and server components
Set up automatic rebuilding of your app if you are using static export
1. Configure webpack for Next.js versions < 14
For Next.js versions 13.0.0 up to (but not including) 14, you need to add a specific webpack configuration to resolve the Flagship SDK correctly in server components:
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, { isServer }) => {
config.resolve.alias = {
...config.resolve.alias,
'@flagship.io/js-sdk': require.resolve('./node_modules/@flagship.io/js-sdk/dist/index.node.commonjs.cjs'),
};
return config;
},
};
module.exports = nextConfig;
This configuration ensures that the server-side Node.js version of the Flagship SDK is used when rendering server components, preventing compatibility issues.
2. Use FlagshipProviderSSR
in server components
FlagshipProviderSSR
in server componentsNext.js 13+ App Router uses server components by default, making it perfect for using FlagshipProviderSSR
. This component initializes Flagship on the server, pre-fetches all flag data, and eliminates any flag flickering in client components.
// app/layout.js (server component)
import { LogLevel, FlagshipProviderSSR } from "@flagship.io/react-sdk";
import Nav from "@/components/Nav";
import "./globals.css";
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default async function RootLayout({ children }) {
return (
<html lang="en">
<body>
<FlagshipProviderSSR
envId={process.env.NEXT_PUBLIC_ENV_ID}
apiKey={process.env.NEXT_PUBLIC_API_KEY}
logLevel={LogLevel.DEBUG}
visitorData={{
id: "visitorId",
hasConsented: true,
context: {
key: "value",
},
}}
>
<div className={"container"}>
<div className="nav">
<Nav />
</div>
<main className={"main"}>{children}</main>
</div>
</FlagshipProviderSSR>
</body>
</html>
);
}
Benefits of using FlagshipProviderSSR
:
Pre-fetches all flag data on the server before HTML is sent to the client
Eliminates flag flickering completely (no need for separate
initialFlagsData
setup)Simplifies integration by handling SDK initialization automatically
Once hydrated on the client, behaves like a normal
FlagshipProvider
📘 Information
FlagshipProviderSSR
is specifically designed for Next.js 13+ App Router. It must be used in a server component.
3. Configure your cache revalidation settings (optional)
Flagship uses HTTP calls to communicate with its servers. With Next.js's built-in support for caching data, some Flagship routes could be cached and deduplicated.
By default, all SDK routes are revalidated after 20 seconds, but you can update this value using the nextFetchConfig
option:
<FlagshipProviderSSR
envId={process.env.NEXT_PUBLIC_ENV_ID}
apiKey={process.env.NEXT_PUBLIC_API_KEY}
visitorData={{
id: "visitorId",
hasConsented: true,
context: {
key: "value"
}
}}
nextFetchConfig={{ revalidate: 15 }} // Set cache revalidation to 15 seconds
>
{children}
</FlagshipProviderSSR>
You can also set this configuration when initializing the SDK programmatically:
// helpers/flagship.js
import { Flagship, FSSdkStatus, DecisionMode, LogLevel } from "@flagship.io/react-sdk";
export async function startFlagshipSDK() {
if (
Flagship.getStatus() &&
Flagship.getStatus() !== FSSdkStatus.SDK_NOT_INITIALIZED
) {
return Flagship; // If it has been initialized, return early
}
return await Flagship.start(
process.env.NEXT_PUBLIC_ENV_ID,
process.env.NEXT_PUBLIC_API_KEY,
{
logLevel: LogLevel.DEBUG,
fetchNow: false,
decisionMode: DecisionMode.DECISION_API,
nextFetchConfig: { revalidate: 15 }, // Set cache revalidation to 15 seconds
}
);
}
4. Use React SDK hooks in client components
Once you've initialized Flagship with FlagshipProviderSSR
, you can use all the React SDK hooks in your client components.
// app/client-component/page.js
'use client'
import { useFsFlag } from "@flagship.io/react-sdk";
export default function ClientComponent() {
// Get the flag `btnColor` using useFsFlag hook
const flag = useFsFlag("btnColor")
const flagValue = flag.getValue("#dc3545")
return (
<>
<h1>This page is a client component</h1>
<p>flag key: btnColor</p>
<p>flag value: {flagValue}</p>
<button style={{ background: flagValue }} >Click me</button>
</>
)
}
Unlike a manual approach, there's no flickering with this setup because FlagshipProviderSSR
has already pre-fetched all flag data on the server before the client component is rendered.
5. Access flags in server components
There are two ways to access flags in server components:
Option 1: Use the Flagship helper to initialize the SDK and create a visitor
// app/server-component/page.js
import { getFsVisitorData } from "@/helpers/flagship";
import { HitType } from "@flagship.io/react-sdk";
export default async function ServerComponent() {
// visitor data
const visitorData = {
id: "visitorId",
context: {
key: "value"
},
hasConsented: true
}
// Get visitor instance
const visitor = await getFsVisitorData(visitorData)
// Get flag `btnColor` using visitor instance
const flag = visitor.getFlag("btnColor")
const flagValue = flag.getValue("#dc3545")
return (
<>
<h1>This page is a server component</h1>
<p>flag key: btnColor</p>
<p>flag value: {flagValue}</p>
<button style={{ background: flagValue }} >Click me</button>
</>
)
}
The helper function in this example initializes the SDK and creates a visitor:
// helpers/flagship.js
export async function getFsVisitorData(visitorData) {
// start the SDK in Decision Api mode et get the Flagship instance
const flagship = await startFlagshipSDK();
// Create a visitor
const visitor = flagship.newVisitor({
visitorId: visitorData.id,
context: visitorData.context,
hasConsented: visitorData.hasConsented,
});
// Fetch flag values for the visitor
await visitor.fetchFlags();
// Return visitor instance
return visitor;
}
Option 2: Create client components for flag access
For more complex use cases, you can create dedicated client components that use the React SDK hooks:
// components/MyFlagComponent.js
'use client'
import { useFsFlag } from "@flagship.io/react-sdk";
export function MyFlagComponent() {
const myFlag = useFsFlag("my_flag_key");
return <p>flag value: {myFlag.getValue("default-value")}</p>
}
Then use this component in your server component:
// app/page.js
import { MyFlagComponent } from "@/components/MyFlagComponent";
export default function Home() {
return (
<>
<h1>Example of Flagship implementation in Next.js 13</h1>
<p>flag key: my_flag_key</p>
<MyFlagComponent />
</>
);
}
6. Send analytics hits from client components
To send analytics hits from client components, use the Flagship SDK:
// components/MyButtonSendHit.js
"use client";
import { useFlagship, HitType, EventCategory } from "@flagship.io/react-sdk";
export function MyButtonSendHit() {
const fs = useFlagship();
const onSendHitClick = () => {
fs.sendHits({
type: HitType.EVENT,
category: EventCategory.ACTION_TRACKING,
action: "click button",
});
};
return (
<button
style={{ width: 100, height: 50 }}
onClick={() => {
onSendHitClick();
}}
>
Send hits
</button>
);
}
7. Send analytics hits from server components (Optional)
You can also send analytics hits directly from server components:
// app/server-component/page.js
import { getFsVisitorData } from "@/helpers/flagship";
import { HitType } from "@flagship.io/react-sdk";
export default async function ServerComponent() {
//visitor data
const visitorData = {
id: "visitorId",
context: {
key: "value",
},
hasConsented: true,
};
//Get visitor instance
const visitor = await getFsVisitorData(visitorData);
//Get flag `btnColor` using visitor instance
const flag = visitor.getFlag("btnColor");
const flagValue = flag.getValue("#dc3545");
// Analytic hits can also be sent from server components (Optional)
visitor.sendHit({
type: HitType.PAGE_VIEW,
documentLocation: "https://example.com/server-component",
});
return (
<>
<h1>This page is a server component</h1>
<p>flag key: btnColor</p>
<p>flag value: {flagValue}</p>
<button style={{ background: flagValue }}>Click me</button>
</>
);
}
When using server components, you'll use the visitor instance's sendHit()
method rather than the sendHits()
method used in client components. This is particularly useful for page view tracking that doesn't require user interaction.
8. Set up automatic rebuilding for static export
If you're using static export, you'll need to set up automatic rebuilding of your app when campaigns are updated in Flagship.
To automate the rebuilding of your application, use Flagship's Webhooks Integrations. When your campaigns are updated in Flagship, a webhook called [environment] synchronized will be triggered and you can use this event to trigger a rebuild of your application to ensure that it reflects the updated flag values.

In this guide, we will deploy our app to Netlify.com, but the process is similar for other platforms and can also be used with a CI/CD pipeline.
1. Once your app is deployed to netlify.com, go to Site Settings -> Build and Deploy and create a build hook.


2. Set up the webhook on the Flagship platform
On the Flagship platform, go to Settings -> Integrations and select the Webhooks tab. Choose the [environment] synchronized event and enter the URL for your Netlify build hook. Then click "Create" to set up the webhook.

Do you have any feedback or suggestions? Would you like to see another tutorial? Contact us with your thoughts [email protected].
You can view the full code for this example on github
Last updated
Was this helpful?