Laravel.io
import mixpanel from 'mixpanel-browser'
import featuresData from './lib/growthbook/features.json'
import { FEATURES_ENDPOINT } from '@lib/contants'
import { GrowthBook } from '@growthbook/growthbook'
import {
  NextFetchEvent,
  NextRequest,
  NextResponse,
  userAgent,
} from 'next/server'

export async function middleware(req: NextRequest, ev: NextFetchEvent) {
  const growthbook = new GrowthBook({
    enableDevMode: process.env.NODE_ENV !== 'production',
    features: featuresData.features,
    trackingCallback: (experiment, result) => {
      mixpanel.track(
        '$experiment_started',
        {
          'Experiment name': experiment.key,
          'Variant name': result.variationId,
          $source: 'growthbook',
        },
        { send_immediately: true },
      )
    },
  })

  mixpanel.init('011425ba7a5b502351ce5e4ba02deeb5', {
    debug: process.env.NEXT_PUBLIC_VERCEL_ENV !== 'production',
    loaded: function(mixpanel) {
      growthbook.setAttributes({
        ...growthbook.getAttributes(),
        id: mixpanel.get_distinct_id()
      });
    }
  });

  // if (process.env.NODE_ENV === 'development') {
  //   const res = await fetch(FEATURES_ENDPOINT)
  //   const json = await res.json()
  //   growthbook.setFeatures(json.features)
  // }

  growthbook.setAttributes({
    browser: userAgent(req).ua,
    url: req.nextUrl.pathname,
  })

  let response = NextResponse.next()
  const features = growthbook.getFeatures()
  for (let key in features) {
    if (!growthbook.isOn(key)) {
      continue
    }

    const value = growthbook.getFeatureValue(key, {}) as any
    if (value.match !== req.nextUrl.pathname) {
      continue
    }

    req.nextUrl.pathname = value.target
    response = NextResponse.rewrite(req.nextUrl)
    break
  }

  return response
}

Please note that all pasted data is publicly available.