Looking for a bit of confirmation here: We have a...
# announcements
b
Looking for a bit of confirmation here: We have a nextjs 13 app that we’ve setup based on the documentation here: https://docs.growthbook.io/guide/nextjs-and-growthbook However, we’re running into some lag time with features loading. We have ignored the SSR implementation identified for the react setup since next13 no longer supports
getServerSideProps
. Is there something we’re missing with next.js 13 that would inhibit SSR?
f
Hi Richard
we have examples of a lot of the SSR and middleware versions of GrowthBook
b
@fresh-football-47124 this is all well and good for next12, but next13 has different requirements. WAnt to make sure we’re not missing any implementation for SSR or if it’s inherent without explicitly calling getServerSideProps
Copy code
export const getServerSideProps: GetServerSideProps = async (context) => {
  const gbContext = getServerSideGrowthBookContext(context);

  const gb = new GrowthBook(gbContext);
  await gb.loadFeatures({ timeout: 1000 });

  const feature1Enabled = gb.isOn("feature1");
  const feature2Value = gb.getFeatureValue("feature2", "fallback");

  return {
    props: {
      feature1Enabled,
      feature2Value,
    },
  };
};
This paradigm doesn’t exist in next13
f
@future-teacher-7046 ^?
f
We don't have examples yet for using the new React Server Components with Next13. I'm pretty sure it's possible to get SSR working, but haven't tested it yet.
b
f
Yeah, something like that might work. The built in SSR helpers in our React SDK likely won't work, but it shouldn't be too hard to recreate what it's doing. Basically do the fetch, then call setFeatures manually on the GrowthBook instance. Then, any time a component uses the feature flag hooks, it will use that fetched data immediately without delay.
b
The issue here is this appears to be the SSR only method, not clientside + SSR. I’m looking for the hybrid variation with next13's new paradigm.
a
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:
Copy code
// 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>
  );
}
Copy code
// 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>
  );
}
Copy code
// app/Layout.tsx
export default function Layout({ children }: Props) {
  return (
    <html lang="en">
      <body>
        <GrowthBookProvider>
          <Nav />
          {children}
          <Footer />
        </GrowthBookProvider>
      </body>
    </html>
  );
}
f
To get A/B testing you need some attribute to split on, like some ID. If it’s the same ID as you use client side, you’ll get the same variation on anywhere the SDK runs.
a
Do I just need to add that attribute when I initialize growthbook, or do I also need to send that id when calling the features endpoint?
f
you need to add the id or hashing attribute before you check if the feature is on or not (or get the value)
that data is not sent to GrowthBook, but used internally by the SDK to figure out exposure
a
I see thanks for the help. I'll check that out