Hi! We are trying to set up A/B testing using the ...
# announcements
b
Hi! We are trying to set up A/B testing using the hybrid ssr/client-side approach described here: https://docs.growthbook.io/lib/react#hybrid-ssr--client-side Question: The code example in the documentation linked above says that when using
gb.setAttributes
on the client side, to "use the same values as SSR when possible". We are using
id
for persistent targeting but we can't know it on the server side due to cache. If the client-side
id
attribute doesn't match server-side
id
, what would the impact be in this case? My guess is there could be a "flash" where the feature flag value changes from what the server-side (cached)
id
was bucketed into, to what the client side
id
gets bucketed into?
s
That's my assumption as well - the user may see content that isn't assigned to them for the short time their
id
attribute is not populated
One alternative would be to withhold rendering the specific component tree until
id
is available (force it to render client-side only)
b
Thanks, we are going to try it and see how it goes. A follow up question, if you don't mind: We are calling
loadFeatures
on the client side, but seeing some inconsistent results. In our local environment, the features are already loaded by default on the server side (which is good, prevents the flicker). But on our staging environment, the features are not loaded until we call
loadFeatures
on the client side and thus we are seeing a flicker. Any idea why that would be? Should we be calling
loadFeatures
on both the server side and client side?
s
It's strange that it works in local but not in staging. How are you instantiating your
GrowthBook
instance? (Assuming it's the same in either environment)
b
On the server side we don't explicitly create an instance, we call
getGrowthBookSSRData
(from the growthbook-react SDK) and pass it our context containing apiHost, clientKey, attributes.id and attributes.environment, all of which are the same between local and staging except for the attributes. Looking at the SDK code, I see that it internally creates an instance and attempts to load the features:
Copy code
// Get features from API and targeting attributes during SSR
export async function getGrowthBookSSRData(
  context: Context
): Promise<GrowthBookSSRData> {
  // Server-side GrowthBook instance
  const gb = new GrowthBook({
    ...context,
  });

  // Load feature flags from network if needed
  if (context.clientKey) {
    await gb.loadFeatures();
  }

  const data: GrowthBookSSRData = {
    attributes: gb.getAttributes(),
    features: gb.getFeatures(),
  };
  gb.destroy();

  return data;
}
So now I'm thinking the
loadFeatures
request here is being blocked somehow in our staging server. I can look deeper into that, unless you have another idea? Would that
loadFeatures
result be logged anywhere that we could look into?
s
That's possible. You should be able to call
getFeatures
on the GB instance (or directly look into
gb._ctx.features
)
b
Yeah when I look into
gb._ctx.features
it's an empty object on the server side
if there was an error in the request made by
loadFeatures
, would that error message be logged somewhere?
s
The devs tell me unfortunately no, there's nothing surfaced at the moment
For now I would recommend doing a manual fetch to the features endpoint to see if your staging environment is indeed blocking it.
b
Okay thanks, we'll try that. Appreciate the help!
🙌 1
Just to follow up, our staging server was indeed blocking requests to growthbook. After fixing that, no more flicker. Then we tried overriding the
id
attribute on the client side, and this caused a flicker when the client id was assigned a different variant than the id corresponding to the page cached at the server side. That's not ideal, but it's what we expected when overriding the value on the client side.