PostHog / posthog

🦔 PostHog provides open-source product analytics, session recording, feature flagging and A/B testing that you can self-host.
https://posthog.com
Other
19.45k stars 1.14k forks source link

No heatmap with reverse-proxy #23272

Open gmilon opened 1 week ago

gmilon commented 1 week ago

Bug Description

Bug description

Not sure if this is something related to our account settings or if it affects other users. We are not getting any heatmap or autocapture events from our web frontend app with a custom proxy.

How to reproduce

  1. Setup a cloudflare worker for eu region:
const API_HOST = "us.i.posthog.com" // Change to "eu.i.posthog.com" for the EU region
const ASSET_HOST = "us-assets.i.posthog.com" // Change to "eu-assets.i.posthog.com" for the EU region

async function handleRequest(request, ctx) {
  const url = new URL(request.url)
  const pathname = url.pathname
  const search = url.search
  const pathWithParams = pathname + search

  if (pathname.startsWith("/static/")) {
      return retrieveStatic(request, pathWithParams, ctx)
  } else {
      return forwardRequest(request, pathWithParams)
  }
}

async function retrieveStatic(request, pathname, ctx) {
  let response = await caches.default.match(request)
  if (!response) {
      response = await fetch(`https://${ASSET_HOST}${pathname}`)
      ctx.waitUntil(caches.default.put(request, response.clone()))
  }
  return response
}

async function forwardRequest(request, pathWithSearch) {
  const originRequest = new Request(request)
  originRequest.headers.delete("cookie")
  return await fetch(`https://${API_HOST}${pathWithSearch}`, originRequest)
}

export default {
  async fetch(request, env, ctx) {
    return handleRequest(request, ctx);
  }
};
  1. Setup the SDK
    posthog.init(apiKey, {
      api_host: 'pdhcustom-proxy-domain.com',
      ui_host: "https://eu.posthog.com",
      persistence: "localStorage+cookie",
      enable_heatmaps: true,
      autocapture: true,
      capture_pageview: false,
      person_profiles: "identified_only",
      loaded: onPostHogReady,
    });

Observations:

We can see the clicks are tracking in the posthog admin, we even see session replay with clicked event attached to it.

It seems like the proxy is working as expected the first /decide API call returns a 200 response with the config.

When we open the heatmap we don't see any data coming from the API: the https://eu.posthog.com/api/heatmap/ endpoint returns a 200 with an empty result:

{"results":[]}

Debug info

- [X] PostHog Cloud, Debug information: 

Session: https://us.posthog.com/project/sTMFPsFhdP1Ssg/replay/01905807-cb51-756b-be99-e28fe86f453a?t=2004 
Admin: http://go/adminOrgEU/018f2d41-518f-0000-fe99-3812604798bd (Project: 21661)
Sentry: http://go/sentryEU/21661
pauldambra commented 1 week ago

let response = await caches.default.match(request)

just a fly-by comment that we keep a short TTL on the main static assets so they update when we release new versions (which happens frequently) so it's worth making sure you're not extending their lifetime too much with his statement 🤞


there are two kinds of heatmaps in posthog

  1. the OG heatmap is a clickmap built from autocapture data, so if that's not being received, the clickmap will be empty
  2. the newer heatmap is built from data that is sent along with other posthog events, when events are sent we add a $heatmap_data property which is extracted during ingestion

if you set posthog.debug(true) in the console, or use the toolbar's event debugger you'll be able to see if events are being sent and if they include heatmap data.

is the site public for us to take a look?