Hey, I was also testing growthbook with the new app router. The implementation is basically what was suggested above, loading features in a server component then passing it down to a client component which contains the GrowthBookProvider component.
Seems to work fine for feature flags, but I wonder if it's also possible to get a/b testing working here. Is there anything special that we can send (like the id) to get the appropriate bucket on the server? Or is that only available client-side.
Here's an example of what we're doing:
// GrowthbookProvider.tsx
export default async function GrowthbookProvider({
children,
}: Props) {
const response = await fetch(`<GROWTHBOOK_API_HOST>/api/features/<GROWTHBOOK_CLIENT_KEY>`,
{
next: {
revalidate: 0,
},
}
);
const { features } = (await response.json()) as { features: AppFeatures };
return (
<GrowthBookClientProvider initialFeatures={features}>
{children}
</GrowthBookClientProvider>
);
}
// GrowthBookClientProvider.tsx
"use client";
//...
type Props = {
children: ReactNode;
initialFeatures: AppFeatures | undefined;
};
export default function GrowthBookClientProvider({
children,
initialFeatures,
}: Props) {
const [growthbook] = useState(
() =>
new GrowthBook<AppFeatures>({
enableDevMode: true,
// @ts-expect-error Record<string, FeatureDefinition<any>>
features: initialFeatures,
trackingCallback(experiment, result) {
console.log("Tracking", experiment, result);
},
})
);
return (
<GrowthBookProvider growthbook={growthbook}>{children}</GrowthBookProvider>
);
}
// app/Layout.tsx
export default function Layout({ children }: Props) {
return (
<html lang="en">
<body>
<GrowthBookProvider>
<Nav />
{children}
<Footer />
</GrowthBookProvider>
</body>
</html>
);
}