I've got this snippet that should set the cookie i...
# ask-questions
b
I've got this snippet that should set the cookie in the middleware (Next.js).
Copy code
const growthbook = new GrowthBook({
    attributes: { id: visitor_id },
    features: await getFeatures(),
    trackingCallback: (experiment, result) => {
      console.log("EXPERIMENT", experiment)
      console.log("RESULT", result)
      res.cookie("GB_EXPERIMENTS", JSON.stringify([
        {
          key: experiment.key,
          variationId: String(result.variationId)
        }
      ]))
    }
  });
f
are the console.log's firing?
are you testing with different id's to change the variation?
b
the console logs are firing
and whenever I see
variantId = 1
I don't get the cookie set
I'm just clearing cookies and refreshing the page
until I get variant 1
f
make sure you're changing the visitor_id.
you could put in the Math.random() to test
can you add a console.log of the visitor_id and paste what you're getting?
b
visitor ID does change
Copy code
EXPERIMENT {
  variations: [ false, true ],
  key: 'prorb',
  coverage: 1,
  weights: [ 0.5, 0.5 ],
  hashAttribute: 'id'
}
RESULT {
  inExperiment: true,
  hashUsed: true,
  variationId: 0,
  value: false,
  hashAttribute: 'id',
  hashValue: '03e900c0-9d56-4df6-8d38-c26c78af5077'
}
Visitor ID 03e900c0-9d56-4df6-8d38-c26c78af5077
EXPERIMENT {
  variations: [ false, true ],
  key: 'prorb',
  coverage: 1,
  weights: [ 0.5, 0.5 ],
  hashAttribute: 'id'
}
RESULT {
  inExperiment: true,
  hashUsed: true,
  variationId: 1,
  value: true,
  hashAttribute: 'id',
  hashValue: '63bab7aa-8739-464a-b30a-1faf4bcf6dfc'
}
Visitor ID 63bab7aa-8739-464a-b30a-1faf4bcf6dfc
f
I'm not sure what you're using to set the cookie, but perhaps that's not working
the variation id looks right
b
what do you mean what I'm using to set the cookie?
because it sets it only on variant 0
f
try this - find a visitor ID that returns variation 1
then change the cookie name, see if that sets it - maybe something is going on in that middleware
b
changed it, and it doesn't set it
can it be something with the call to
res.cookie
?
cause everything else works fine
but I don't understand what does it have anything to do with variant 1...
could it be that the trackingCallback function fires too late? after the response is returned to the browser?
f
possibly
but if that were true, it wouldn't set the cookie at all
b
well, it could be something different about the callback on variants
not the control
I'm just guessing
I didn't look at the code
b
fwiw, you're continuously setting the same cookie here - you'd need to aggregate all the experiments into one array before setting, or it'll keep overwriting
ie if there's more than one call of trackingCallback/more than one experiment, it probably won't behave as expected
b
I'm only calling
trackingCallback
once, in the middleware
f
@future-teacher-7046 might have some ideas when he's up in a few hours
f
I think I know what's going on. Are you doing a redirect for variation 1? If so, you have to make sure to set the cookie on the redirect response in addition to the normal response. https://github.com/vercel/next.js/discussions/34822
b
hmmm...
Copy code
// Pick which page to render depending on a feature flag
  let res = NextResponse.next();
  if (growthbook.feature("prorb").on) {
    const url = req.nextUrl.clone();
    url.pathname = "/lp/practical-ruby-on-rails-for-beginners-20220618";
    res = NextResponse.rewrite(url);
  }
f
Yes, it's that
res = NextResponse.rewrite
part that's causing the issue. When you create a new response object it loses everything you did earlier such as setting cookies
b
I see... ok, let me try and fix that.
f
To fix it, I would have the tracking callback update a variable instead of setting a cookie directly. Then before you return a response object, set the cookie on it.
b
yeah, thank you
should
growthbook.isOn("prorb")
return false?
Even though I've enabled it...
f
Yes. isOn will be false if the flag is "off" for the user
b
ah, ok... so it's going to be "on" just for people who see the variant?
f
Correct
b
Cool, so it seems to work now. Does this code look right to you? Is there anything I'm missing?
Copy code
let visitor_id = req.cookies[COOKIE] || crypto.randomUUID()
  let experimentKey = null;
  let variantId = null;

  const growthbook = new GrowthBook({
    attributes: { id: visitor_id },
    features: await getFeatures(),
    trackingCallback: (experiment, result) => {
      experimentKey = experiment.key;
      variantId = result.variationId;
    }
  });

  // Pick which page to render depending on a feature flag
  let res = NextResponse.next();

  if (growthbook.feature("prorb").on) {
    const url = req.nextUrl.clone();
    url.pathname = "/lp/practical-ruby-on-rails-for-beginners-20220618";
    res = NextResponse.rewrite(url);

  }
  res.cookie("GB_EXPERIMENTS", JSON.stringify([
    {
      key: experimentKey,
      variationId: variantId
    }
  ]))

  // Store the visitor cookie if not already there
  if (!req.cookies[COOKIE]) {
    res.cookie(COOKIE, visitor_id)
  }

  return res
f
yes, that looks ok to me, as long as your front-end code can handle when the key and variationId in the cookie are null (e.g. if you turn off the experiment)
b
Awesome, thank you for your help.