https://www.growthbook.io/ logo
b

bumpy-student-89073

06/18/2022, 1:18 PM
The thing is, I'm using a middleware for A/B testing, and I'm not exactly sure how to get the Mixpanel distinct id in this middleware, or even if I can access it.
f

fresh-football-47124

06/18/2022, 1:20 PM
Hi Cezar
let me find you my sample code for Mixpanel...
Copy code
mixpanel.init('6a37b4557......[replace]', {
    debug: true,
    loaded: function(mx) {
        growthbook.setAttributes({
            ...growthbook.getAttributes(),
            id: mx.get_distinct_id()
        });
    }
});
b

bumpy-student-89073

06/18/2022, 1:21 PM
Here's what I've got.
I'm initializing the Mixpanel lib (using the
mixpanel-browser
package) in the
_app.js
file.
which, I think is already too late...
f

fresh-football-47124

06/18/2022, 1:23 PM
you can update the attributes with setAttributes (which replaces all the attributes)
Did you try that sample code?
b

bumpy-student-89073

06/18/2022, 1:24 PM
oh, so if I do this in
_app.js
...
Copy code
const growthbook = new GrowthBook({
    attributes: { id: visitor_id },
    features: await getFeatures(),
    trackingCallback: (experiment, result) => {
      mixpanel.track("$experiment_started", {
        "Experiment name": experiment.key,
        "Variant name": result.variationId
      });
    }
  });
I did try it, but it didn't work
f

fresh-football-47124

06/18/2022, 1:27 PM
is that the only attribute your adding?
b

bumpy-student-89073

06/18/2022, 1:28 PM
well, yeah... for now... just trying to set it up
this code
Copy code
const growthbook = new GrowthBook({
    attributes: { id: visitor_id },
    features: await getFeatures(),
    trackingCallback: (experiment, result) => {
      mixpanel.track("$experiment_started", {
        "Experiment name": experiment.key,
        "Variant name": result.variationId
      });
    }
  });
gives me an error...
Copy code
TypeError: Cannot read properties of undefined (reading 'disable_all_events')
    at MixpanelLib._event_is_disabled (webpack-internal:///(middleware)/./node_modules/mixpanel-browser/dist/mixpanel.cjs.js:5561:21)
    at MixpanelLib.eval (webpack-internal:///(middleware)/./node_modules/mixpanel-browser/dist/mixpanel.cjs.js:4776:14)
    at MixpanelLib.eval [as track] (webpack-internal:///(middleware)/./node_modules/mixpanel-browser/dist/mixpanel.cjs.js:2789:27)
    at Object.trackingCallback (webpack-internal:///(middleware)/./pages/_middleware.ts:45:69)
    at GrowthBook.track (webpack-internal:///(middleware)/./node_modules/@growthbook/growthbook/dist/esm/GrowthBook.js:498:20)
    at GrowthBook._run (webpack-internal:///(middleware)/./node_modules/@growthbook/growthbook/dist/esm/GrowthBook.js:473:10)
    at GrowthBook.run (webpack-internal:///(middleware)/./node_modules/@growthbook/growthbook/dist/esm/GrowthBook.js:126:25)
    at GrowthBook.evalFeature (webpack-internal:///(middleware)/./node_modules/@growthbook/growthbook/dist/esm/GrowthBook.js:311:26)
    at GrowthBook.feature (webpack-internal:///(middleware)/./node_modules/@growthbook/growthbook/dist/esm/GrowthBook.js:220:17)
    at Object.middleware [as handler] (webpack-internal:///(middleware)/./pages/_middleware.ts:53:20)
I"m guessing the
mixpanel
object doesn't make sense in the context of a middleware?
f

fresh-football-47124

06/18/2022, 1:29 PM
could be
This is how I got it working in my NextJS app (using _app.tsx):
Copy code
const growthbook = new GrowthBook({
  trackingCallback: (experiment, result) => {
      mixpanel.track("Experiment Viewed",
          {
              'Experiment Id': experiment.key,
              'Variant Id' : result.variationId
          }
      );
  }
});

mixpanel.init('60c30...b4557', {
    debug: true,
    loaded: function(mx) {
        growthbook.setAttributes({
            ...growthbook.getAttributes(),
            id: mx.get_distinct_id()
        });
    }
});

const FEATURES_ENDPOINT = "<http://localhost:3100/api/features/key_dev_e...5365>";

function MyApp({ Component, pageProps }: AppProps) {

    useEffect(() => {
    // Load feature definitions from API
    fetch(FEATURES_ENDPOINT)
        .then((res) => res.json())
        .then((json) => {
          growthbook.setFeatures(json.features);
        });

    // TODO: replace with real targeting attributes
    growthbook.setAttributes({
      "id": "432",
      "deviceId": "foo",
      "company": "foo",
      "loggedIn": true,
      "employee": true,
      "country": "foo",
      "browser": "foo",
      "url": "foo"
    })
  }, [])

  return (
      <GrowthBookProvider growthbook={growthbook}>
        <Component {...pageProps} />
      </GrowthBookProvider>
  )
}
But I haven't tested using the middleware
@future-teacher-7046 can help you when he's around
b

bumpy-student-89073

06/18/2022, 1:37 PM
It seems Mixpanel has another package for Node, but using that I get an error as well.
Copy code
You're using a Node.js module (events) which is not supported in the Edge Runtime.
f

future-teacher-7046

06/18/2022, 1:45 PM
I can't find very much about using Mixpanel from within Next.js middleware so not sure if that's possible. I also don't think you'll be able to get the distinct id there easily.
One option is to use your own visitor id cookie for assigning variations. Then pass the result to the front end in a cookie and track it in Mixpanel when the page loads.
b

bumpy-student-89073

06/18/2022, 1:49 PM
Would creating 2 instances of GrowthBook work? Like this: in the middleware
Copy code
// Get existing visitor cookie or create a new one
  let visitor_id = req.cookies[COOKIE] || crypto.randomUUID()

  const growthbook = new GrowthBook({
    attributes: { id: visitor_id },
    features: await getFeatures()
  });
and then in
_app.js
Copy code
new GrowthBook({
      attributes: { id: mixpanel_id },
      trackingCallback: (experiment, result) => {
        mixNode.track("$experiment_started", {
          "Experiment name": experiment.key,
          "Variant name": result.variationId
        });
      }
    });
f

future-teacher-7046

06/18/2022, 1:51 PM
The tracking callback only fires on the same GrowthBook instance where you evaluate a feature value.
b

bumpy-student-89073

06/18/2022, 1:51 PM
oh, so it wouldn't work
One option is to use your own visitor id cookie for assigning variations. Then pass the result to the front end in a cookie and track it in Mixpanel when the page loads.
Do you have an example of this?
I can't visualize how that works.
f

future-teacher-7046

06/18/2022, 2:01 PM
In your middleware, set a cookie with the experiment key and assigned variation
Copy code
res.cookie("GB_EXPERIMENTS", JSON.stringify([{key: "my-experiment", variationId: 1}])
Then in your
_app.js
track in mixpanel:
Copy code
useEffect(() => {
  const experiments = document.cookie["GB_EXPERIMENTS")
  if (!experiments) return;
  const parsed = JSON.parse(experiments);
  if (!parsed) return;
  parsed.forEach(res => {
    mixpanel.track("$experiment_started", {
      "Experiment name": res.key,
      "Variant name": res.variationId
    })
  })
}, [])
b

bumpy-student-89073

06/18/2022, 2:32 PM
Cool, that seems to work. Thank you.
3 Views