Skip to content

Experimental repo to integrate LD with the Next.js App Router.

License

Notifications You must be signed in to change notification settings

launchdarkly-labs/ld-nextjs

Repository files navigation

Important

This is an experimental project to demonstrate the use of LaunchDarkly with Next.js App Router.

This is designed for the App Router. Pages router is not supported.

This solution uses the Node Server SDK and the Javascript SDK. It features:

  • Server side rendering with both Server Components and Client Components.
  • A client example located in /app/components/helloLDClient.tsx
  • A React Server Component (RSC) example in /app/components/helloLDRSC.tsx
  • A universal variation method for calling features on both client and server.

This is a Next.js project bootstrapped with create-next-app using App Router.

Quickstart

To run this project:

  1. Update the .env.local file with your LaunchDarkly SDK Key configurations.
LD_SDK_KEY='<YOUR LD SERVER SDK KEY>'
NEXT_PUBLIC_LD_CLIENT_SIDE_ID='<YOUR LD CLIENT SDK KEY>'

Optional -

  1. Either create dev-test-flag in your LaunchDarkly environment or replace with your own flags in helloLDClient.tsx and/or helloLDRSC.tsx.
  2. yarn && yarn dev or npm i && npm run dev

You should see your flag value rendered in the browser.

API

The code under ld exposes server and client apis.

Server API

  • initNodeSdk - Initializes the Node SDK on server startup using the instrumentation hook

  • getBootstrap - Returns a json suitable for bootstrapping the js sdk.

  • useLDClientRsc - Use this to get an ldClient for Server Components.

Client API

  • LDProvider - The react context provider.

  • useLDClient - Use this to get an ldClient for Client Components.

How to use this in your own project

Follow these instructions if you want to test this apis in your own project:

  1. Enable instrumentationHook in next.config.mjs:
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: { instrumentationHook: true },
};

export default nextConfig;
  1. Create a new file instrumentation.ts at the root of your project. This will initialize the Node Server SDK.
import { initNodeSdk } from '@/ld/server';

export async function register() {
  await initNodeSdk();
}
  1. In your root layout component, render the LDProvider using your LDContext and bootstrap:
export default async function RootLayout({
  children,
}: Readonly<{
  children: ReactNode;
}>) {
  // You must supply an LDContext. For example, here getLDContext
  // inspects cookies and defaults to anonymous.
  const context = getLDContext();

  // A bootstrap is required to initialize LDProvider.
  const bootstrap = await getBootstrap(context);

  return (
    <html lang="en">
      <body className={inter.className}>
        <LDProvider context={context} options={{ bootstrap }}>
          {children}
        </LDProvider>
      </body>
    </html>
  );
}
  1. Server Components must use the useLDClientRsc function, and can be async or non-async:
// You should use your own getLDContext function.
import { getLDContext } from '@/app/utils';
import { useLDClientRsc } from '@/ld/server';

export default async function HelloRSC() {
  const ldc = await useLDClientRsc(getLDContext());
  const flagValue = ldc.variation('dev-test-flag');

  return (
    <div className="border-2 border-white/20 p-4">
      <p className="text-xl ldgradient">
        {flagValue
          ? "This flag is evaluating True in a React Server Component"
          : "This flag is evaluating False in a React Server Component"}
      </p>
    </div>
  );
}
  1. Client Components must use the useLDClient hook:
'use client';

import { useLDClient } from '@/ld/client';

export default function HelloClient() {
  const ldc = useLDClient();
  const flagValue = ldc.variation('dev-test-flag');

  return (
    <div className="border-2 border-white/20  p-4 ">
      <p className="ldgradient text-xl">
        {flagValue
          ? "This flag is evaluating True running Client-Side JavaScript"
          : "This flag is evaluating False running Client-Side JavaScript"}
      </p>
    </div>
  );
}

You will see both components are rendered on the server (view source on your browser). However, only Client Components will respond to live changes.

About

Experimental repo to integrate LD with the Next.js App Router.

Resources

License

Stars

Watchers

Forks

Packages

No packages published