Giter Site home page Giter Site logo

posthog / posthog-js-lite Goto Github PK

View Code? Open in Web Editor NEW
50.0 50.0 27.0 3.74 MB

Reimplementation of posthog-js to be as light and modular as possible.

Home Page: https://posthog.com/docs/libraries

License: MIT License

JavaScript 1.58% TypeScript 98.42%
node posthog react-native sdk web

posthog-js-lite's People

Contributors

adamdorwart avatar benjackwhite avatar chfinst avatar dependabot[bot] avatar edscode avatar hansottowirtz avatar ivanagas avatar jonatthu avatar joshkel avatar liyiy avatar macobo avatar marandaneto avatar mariusandra avatar mmmoussa avatar mosattler avatar neilkakkar avatar paolodamico avatar pauldambra avatar robbie-c avatar stefanmaric avatar steffanlevet avatar timgl avatar twixes avatar yakkomajuri avatar zakharchenkoandrii avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

posthog-js-lite's Issues

Asynchronous calls of ´isFeatureEnabled´ fail to resolve

Bug description

Asynchronous calls of isFeatureEnabled fail to resolve when no personal API key is provided.

Tested on:

How to reproduce

import { PostHog } from "posthog-node";

const { POSTHOG_API_KEY } = process.env;

if (!POSTHOG_API_KEY) {
    throw Error("PostHog API key not provided.");
}

const posthog = new PostHog(POSTHOG_API_KEY);

async function main() {
    const distinctId = "1337";
    const key = "AWESOME_FEATURE";

    const featureFlags = await Promise.all([
        posthog.isFeatureEnabled(key, distinctId),
        posthog.isFeatureEnabled(key, distinctId),
        posthog.isFeatureEnabled(key, distinctId),
        posthog.isFeatureEnabled(key, distinctId),
        posthog.isFeatureEnabled(key, distinctId),
        posthog.isFeatureEnabled(key, distinctId),
        posthog.isFeatureEnabled(key, distinctId),
        posthog.isFeatureEnabled(key, distinctId),
    ]);

    console.log(featureFlags);
}

main()
    .then(() => {
        process.exit(0);
    })
    .catch((err) => {
        console.error(err);
        process.exit(-1);
    });

The expected result would be:

[
  true, true,
  true, true,
  true, true,
  true, true
]

But instead, we got:

[
  undefined, true,
  undefined, undefined,
  undefined, undefined,
  undefined, undefined
]

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

  • If we provide a personal API key, the feature flags will be evaluated as expected.
  • If we individually await the isFeatureEnabled calls instead of grouping them inside a Promise.all, the feature flags will be evaluated correctly.
for (let i = 0; i < 8; i++) {
    const ff = await posthog.isFeatureEnabled(key, distinctId);
    console.log(ff);
}
// -> false
// -> false
// -> false
// -> false
// -> false
// -> false
// -> false
// -> false

Document initAsync method for RN

Is your feature request related to a problem?

If users try to directly use Posthog on initialisation, it is possible that the async filesystem queries to preload storage won't have fired. We should document this as the case so that they are able to use initAsync to work around this.

NOTE: This shouldn't affect users with the PosthogProvider but only those who choose to use the PostHog class directly.

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your feature request – we love each and every one!

How to get feature flag variants in react-native?

I would like to get feature-flag variants in react native.

  • getFeatureFlags() seems to only return an array of flag names (even though the typing indicates otherwise).
  • getFeatureFlag() does not seem to work at all and only returns false, no matter if a flag is set or not.

`Application Became Active` event on RN should have been `Application Opened` with `from_background=true` property

Description

RN has a specific event called Application Became Active when the app is active which means the app is back in the foreground.
On the other Mobile SDKs, we just capture the Application Opened event with the from_background=true property instead.

Ideally, we'd align this behavior in one way or the other.

When mobile dashboard templates are shipped, templates should have a single source of truth for events and properties.

Can't await captures with `sendFeatureFlags`

Bug description

Normally, this works:

posthog.capture({
  distinctId,
  event: "Purchase"
});
await posthog.flushAsync()

but this doesn't work (flushAsync doesn't flush this capture):

posthog.capture({
  distinctId,
  event: "Purchase",
  sendFeatureFlags: true
});
await posthog.flushAsync()

because super.getFeatureFlagsStateless is not waited-on on this line:

super.getFeatureFlagsStateless(distinctId, groups, undefined, undefined, disableGeoip).then((flags) => {
const featureVariantProperties: Record<string, string | boolean> = {}

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Axios upgrade breaks non-Node runtimes

Bug description

#122 breaks non-Node runtimes by introducing dependencies on Node internals which weren’t present in the previous version of Axios. This is because Axios v1 doesn’t provide the correct non-Node exports, which leads them to try and import a bunch of Node libraries, which they can’t.

A few potential fixes off the top of my head:

  1. Replace Axios with fetch (now that fetch is in all LTS versions, this might not be unreasonable; it would also mean non-Node runtimes don’t have to add fetch as a parameter when instantiating PostHog)
  2. Agitate Axios to fix axios/axios#5495
  3. Patch it
  4. Split the package into Node and non-Node in package.json#exports

(I posted this as a comment on that PR but I’ve upgraded it to an issue so it doesn’t get lost)

RN: expo-file-system could not be found within the project or in these directories (posthog-react-native >= 2.10.2)

Bug description

In a bare React Native app environment, the following error occurs during Metro bundling when only using @react-native-async-storage/async-storage. This issue occurs in a non-Web environment and when expo-file-system is not installed.

BUNDLE  ./index.js

error: Error: Unable to resolve module expo-file-system from /Users/dev/sample-project-name/node_modules/posthog-react-native/lib/posthog-react-native/src/optional/OptionalExpoFileSystem.js: expo-file-system could not be found within the project or in these directories:
  node_modules
  ../node_modules
  ../../node_modules
> 1 | "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.OptionalExpoFileSystem=void 0;var _reactNative=require("react-native");var OptionalExpoFileSystem=undefined;exports.OptionalExpoFileSystem=OptionalExpoFileSystem;try{if(_reactNative.Platform.OS!=='web'){exports.OptionalExpoFileSystem=OptionalExpoFileSystem=require('expo-file-system');}}catch(e){}
    |                                                                                                                                                                                                                                                                                                                                                         ^
    at ModuleResolver.resolveDependency (/Users/dev/sample-project-name/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:153:15)
    at DependencyGraph.resolveDependency (/Users/dev/sample-project-name/node_modules/metro/src/node-haste/DependencyGraph.js:271:43)
    at /Users/dev/sample-project-name/node_modules/metro/src/lib/transformHelpers.js:176:21
    at resolveDependencies (/Users/dev/sample-project-name/node_modules/metro/src/DeltaBundler/buildSubgraph.js:56:25)
    at visit (/Users/dev/sample-project-name/node_modules/metro/src/DeltaBundler/buildSubgraph.js:107:30)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Promise.all (index 8)
    at async visit (/Users/dev/sample-project-name/node_modules/metro/src/DeltaBundler/buildSubgraph.js:116:5)
    at async Promise.all (index 12)
    at async visit (/Users/dev/sample-project-name/node_modules/metro/src/DeltaBundler/buildSubgraph.js:116:5)

The operating environment is as follows.

System:
  OS: macOS 14.2.1
  CPU: (8) arm64 Apple M1 Pro
  Memory: 235.34 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.16.0
  Yarn:
    version: 4.0.2
  npm:
    version: 9.5.1
  Watchman:
    version: 2023.12.04.00
Managers:
  CocoaPods:
    version: 1.14.3
Languages:
  Java:
    version: 17.0.10
  Ruby:
    version: 3.3.0
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.73.2
    wanted: 0.73.2
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

How to reproduce

  1. Install posthog-react-native version 2.10.2 or higher in any React Native project.
  2. Build and run.

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

  • I am currently using React Native version 0.73, but the issue also occurs with versions 0.72 and 0.71.
  • Versions below 2.10.2 are working normally. The issue seems to be caused by the addition of an if statement in version 2.10.2, intended to prevent the operation of expo-file-system on the web platform.

Thank you for your bug report – we love squashing them!

react-native: PostHogCore types not imported

Bug description

Import PostHogCore missing the /src directory
File: posthog-react-native/src/posthog-rn.d.ts
Line: 1

'../../posthog-core';
should be
'../../posthog-core/src';

How to reproduce

  1. Call .capture or .identify
  2. then run tsc command
  3. You will get the below errors:

Property 'capture' does not exist on type 'PostHog'.
Property 'identify' does not exist on type 'PostHog'.

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Related commit 4a707f

Posthog Survey on react native

Hello!

Not sure if this is the correct place to ask, and haven't find anything in the documentation - is Posthog Surveys available for react native ? If it is, how can it be enabled and if it's not, is there any plans of making it?

Thank you!

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Feature flag schema issues

The new version seems to send a new $enabled_feature_flags property with events, which isn't used elsewhere.

Instead, what we'd expect to see are $feature/<feature-key> properties where the value is the value of the flag.

Allow to use `capture` without passing in `distinctId`

Is your feature request related to a problem?

It's possible that events happen, where we cannot bind it to a certain authenticated user. This is the reason why in the JS SDK, we have a capture function that optionally allows us to pass in the distinctId

Describe the solution you'd like

Make distinctId optional in the capture function.

Describe alternatives you've considered

I have no alternative as I'm forced to pass in the distinctId

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your feature request – we love each and every one!

Expose distinct UUID generation and parser/constructor for cookie payload

Is your feature request related to a problem?

I'd love to hand out one URL domain.com/download-app to send users to the android and apple stores by having a dynamic redirect depending on the user agent visiting that page in place — of course I'd love to track this event in PostHog.

Initiating the client inside a lambda function is straight forward, there are two things I'm doing manually right now:

  • reading the cookie headers, checking for an existing PH cookie and grabbing the distinct_id from there.
  • generate a new v4 uuid() if there is no PH header present (the phone did not visit our main landing page before) and write it into a cookie via Set-Cookie header which the client side PostHog then picks up and continues to use when the phone visits our domain.com.

All that works great!

I noticed that ph uses this generateUUID function but does not export it on the posthog-node package. The anonymous uuids seem to share a common prefix 081b in my case, which differs from what the v4 uuids are looking which I am generating (via uuid).

Also parsing and constructing the cookie myself feels error prone, exposing those three building blocks from the lib would make this future proof.

Describe the solution you'd like

  • export the generateUUID function to reuse it
  • export a method to construct the cookie payload
  • export a method to parse a PH cookie payload

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your feature request – we love each and every one!

posthog-react-native 2.X doesn't send autocaptured “Application Installed” event

Bug description

The native SDKs send this

Which means that 1.X of posthog-react-native (which was a wrapper around the iOS/Android SDK) sent it too. 2.X does not send this, and some users who have upgraded to 2.X have asked about this:

How to reproduce

  1. Add [email protected] to app
  2. Install app
  3. Observe events in dashboard
  4. Add [email protected] to app
  5. Install app
  6. Observe (lack of) events in dashboard

Related sub-libraries

  • posthog-react-native

Additional context

Thank you for your bug report – we love squashing them!

CanceledError: canceled on posthog-node 2.2.1 due to unreasonable timeout

Bug description

The request fails due to the default request timeout being 10ms, when not set otherwise

this.requestTimeout = options?.requestTimeout ?? 10

You should change the default timeout to a more reasonable number

How to reproduce

  1. Send an event with posthog.capture() method
  2. Flush/shutdown the client with posthog.shutdown()

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

See the issue on our repository: stepci/stepci#74

Thanks to @koki-develop for finding the bug

Add support for Redis server-side local cache evaluation

Is your feature request related to a problem?

For distributed systems each client is using a local cache which will increase the number of requests to fetch the same configs for X connected services

Describe the solution you'd like

Redis is an in-memory data structure store, used as a distributed, in-memory key–value database, cache and message broker, with optional durability.
We can use Redis caching for local evaluation instead of local memory and set the personal key token in only one service or worker to fetch the feature flags configs and save it on the Redis cache which is shared across all services.

Describe alternatives you've considered

Related sub-libraries

redis

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your feature request – we love each and every one!

Revert back to using node-fetch

We're now using undici for our HTTP client, but unfortunately undici.fetch only works on Node >= 16.8.

This is mentioned in the docs, and you can see it in their code:

if (nodeMajor > 16 || (nodeMajor === 16 && nodeMinor >= 8)) {
  let fetchImpl = null
  module.exports.fetch = async function fetch (resource) {
    if (!fetchImpl) {
      fetchImpl = require('./lib/fetch')
    }
    const dispatcher = (arguments[1] && arguments[1].dispatcher) || getGlobalDispatcher()
    return fetchImpl.apply(dispatcher, arguments)
  }
  // ...
}

I'd love if we could revert back to node-fetch (or something else) to unblock what I believe is the vast majority of our users, since I doubt many people are running Node versions above that.

More context: https://posthogusers.slack.com/archives/C01GLBKHKQT/p1662474954526869

Written at @benjackwhite's request - I'm happy to take this though if you're massively busy

posthog-node uses shared context...

posthog-node uses a shared client and each client is expected to be instantiated per user (just how the browser expects it), however in the case of node, judging from what I see in code, identify calls set the dictinctID in the shared context then when a flush happens, they'll get the last called identify call.

I.E. Two requests come in at the same time, identify(1) and identify(2) comes right before flush, the payloads are then all built using ID = 2.

So I think to get it to work, every where an internal method is called, you need to create a new instance of PostHog, but I don't think this is expected.

Publish posthog-core to npm

Is your feature request related to a problem?

We're currently implementing PostHog into our Next.js app-dir-based application. We want to send events from several locations in the code, including middleware, RSC, route handlers and browser. For RSC and route handlers, we want a way to conveniently initialize a PostHog client for each request from the cookies sent by the browser to take over the cookies.

Describe the solution you'd like

We'd like to directly use PostHogCore from posthog-core to implement this wrapper, including initialization from headers, and memory persistant storage.

Describe alternatives you've considered

Currently, we're subclassing the exported PostHog from posthog-js-lite. Works, but does not feel right.

Posthog node crashes in cloudflare environment

Bug description

I'm trying to use posthog in remixjs / cloudflare pages, but it fails to create an instance of PostHog. Feels like it's trying to use axios under the hood? That's especially weird, since I'm explicitly passing it "fetch" defined globally.

Thoughts?

Am I doing something wrong?

How to reproduce

import { PostHog } from 'posthog-node'

export default function getPosthogServer(env: any) {
  return new PostHog(env.POSTHOG_API_KEY, {
    host: 'https://eu.posthog.com',
    fetch: fetch,
    // enable: env.NODE_ENV === 'production',
  })
}

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your bug report – we love squashing them!

Early Access Management on the server side

It would be great to have the early access management on the server side too. I'm in the process of implementing invitation emails and this would be the exact feature I'd need to make it happen.

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Node version <15 support

Is your feature request related to a problem?

Library only works with node >=15 and above due to AbortController/AbortSignal support.

Describe the solution you'd like

Potentially polyfill the classes

Describe alternatives you've considered

Being explicit about node.js support

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Node 14 is maintained security-wise until ~May 2023

Thank you for your feature request – we love each and every one!

Couldn't find a navigation object

Bug description

(Reposted for @trobbertze)

Hi

I am currently evaluating Posthog for a React Native app.

I am getting the same error as logged in this issue:

PostHog/posthog#11880

What I have found is that in our app the NavigationContainer is not the highest order component (if I can call it that). It is wrapped in a SafeAreaProvider, SafeAreaView and SideMenu components.

If I remove these components and make the NavigationContainer the highest order component, then I do not get the error. But unfortunately my app requires those.

So my question is this, is it possible to have Posthog working when the NavigationContainer is not the highest order component?

How to reproduce

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your bug report – we love squashing them!

RN: Allow alternative native modules to Expo's

Is your feature request related to a problem?

We utilize modules from Expo to interact with native functions we need that are not built into React Native. We already have a way of optionally importing modules so that we don't have to have dependencies that will require native changes. If we could expand this to include multiple supported popular libraries, then we could list them as optionalDependencies and document the two approaches - Expo or not Expo.

Describe the solution you'd like

We currently use a few Expo modules. For each we would need an alternative non-expo library to offer as an alternative. Then we could:

  1. Wrap the usage of these to check first for one type of package, then the other
  2. Expose a strongly typed API and allow the user to override this. That way we can offer either use of a built in package, OR Expo OR your own implementation.

Describe alternatives you've considered

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your feature request – we love each and every one!

"Error: Maximum call stack size exceeded in execute function"

Bug description

The code is causing a maximum call stack size exceeded error.

How to reproduce

  1. Load the code that contains the execute function.
  2. Call the execute function passing an array of SnippetArrayItem and thisArg as parameters.
  3. The code will get stuck in an infinite loop, eventually throwing the RangeError: Maximum call stack size exceeded error.

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

The error is occurring in the execute function, which contains a loop that calls itself recursively. This is causing the stack to fill up until it reaches the maximum size allowed by the browser, resulting in the error.

Thank you for your bug report – we love squashing them!

Don't complain about "initAsync called twice" when hot reloading

Is your feature request related to a problem?

Similar to #113 — every time my React Native app is loaded, reloaded, or the base layout changes (we're using expo-router), PostHog throws up a giant warning:

PostHog.initAsync called twice with the same apiKey. The first instance will be used.

It would be nice to disable this message when __DEV__ is true.

Recoil, a state management library for React, had a similar behavior with singletons and hot reloading and solved this by allowing developers to add a RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED=false setting: facebookexperimental/Recoil#733

Describe the solution you'd like

Some kind of setting, maybe in PostHogProvider, like dangerouslyIgnoreReinitialization or iKnowWhatImDoing={__DEV__} or something, that removes this warning.

Describe alternatives you've considered

  • Patching the package with patch-package

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

<3

RN: Opening chrome dev tools can cause a crash

Bug description

A couple of users have reported that when devving locally, opening the developer tools (chrome) causes the app to crash. It seems to be related to the use of native sync calls probably coming from our use of device-info react-native-device-info/react-native-device-info#776

One user documented their workaround that we should either also implement or (ideally) workaround

/** https://stackoverflow.com/a/60041699 */
const WITH_CHROME_DEBUGGER = !global.nativeCallSyncHook;

/** Posthog causes a crash in Chrome debug thus we disable it if chrome debugger is on */
export const DISABLE_POSTHOG = __DEV__ && WITH_CHROME_DEBUGGER;

export const isPosthogDisabled = (
    _posthogPromise: Promise<PostHog> | Promise<undefined>
): _posthogPromise is Promise<undefined> => {
    return DISABLE_POSTHOG;
};

const posthogPromise = DISABLE_POSTHOG
    ? Promise.resolve(undefined)
    : PostHog.initAsync(POSTHOG_API_KEY, { host: POSTHOG_HOST })

const SharedPosthogProvider: FC = ({ children }) => {
    useLifecycleTracker();

    if (isPosthogDisabled(posthogPromise)) {
        console.warn(`Posthog tracking is disabled.`);
        return <>{children}</>;
    }

    return (
        <PostHogProvider
            client={posthogPromise}
            autocapture={{
                captureLifecycleEvents: false,
                captureTouches: true,
            }}
        >
            {children}
        </PostHogProvider>
    );
};

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your bug report – we love squashing them!

OptIn not possible when enable=false

Bug description

Please describe.

How to reproduce

  1. use a PostHogProvider with the option enable: false
  2. call optIn() on the object returned from the usePostHog hook
  3. Verify that no user events are posted to PostHog

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your bug report – we love squashing them!

Sentry Integration for `posthog-node`

I love the PostHog Sentry integration on the client-side, so I rewrote it for posthog-node:

import {
  type Event,
  type EventProcessor,
  type Exception,
  type Hub,
  type Integration,
  type Primitive,
} from "@sentry/types";
import { type PostHog } from "posthog-node";

interface PostHogSentryExceptionProperties {
  $sentry_event_id?: string;
  $sentry_exception?: { values?: Exception[] };
  $sentry_exception_message?: string;
  $sentry_exception_type?: string;
  $sentry_tags: { [key: string]: Primitive };
  $sentry_url?: string;
  $exception_type?: string;
  $exception_message?: string;
  $exception_source?: string;
  $exception_lineno?: number;
  $exception_colno?: number;
  $exception_DOMException_code?: string;
  $exception_is_synthetic?: boolean;
  $exception_stack_trace_raw?: string;
  $exception_handled?: boolean;
  $exception_personURL?: string;
}

export class PostHogLink implements Integration {
  public readonly name = "posthog-node";

  public constructor(
    private readonly posthog: PostHog,
    private readonly posthogHost: string,
    private readonly organization?: string,
    private readonly prefix?: string
  ) {}

  public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub) {
    addGlobalEventProcessor((event: Event) => {
      if (event.exception?.values === undefined || event.exception.values.length === 0) {
        return event;
      }

      if (!event.tags) {
        event.tags = {};
      }

      const sentry = getCurrentHub();
      const userId = sentry.getScope().getUser()?.id?.toString();

      if (userId === undefined) {
        // If we can't find a user ID, don't bother linking the event. We won't be able to send anything meaningful to PostHog without it.
        return event;
      }

      event.tags["PostHog Person URL"] = new URL(`/person/${userId}`, this.posthogHost).toString();

      const properties: PostHogSentryExceptionProperties = {
        // PostHog Exception Properties
        $exception_message: event.exception.values[0]?.value,
        $exception_type: event.exception.values[0]?.type,
        $exception_personURL: event.tags["PostHog Person URL"],
        // Sentry Exception Properties
        $sentry_event_id: event.event_id,
        $sentry_exception: event.exception,
        $sentry_exception_message: event.exception.values[0]?.value,
        $sentry_exception_type: event.exception.values[0]?.type,
        $sentry_tags: event.tags,
      };

      const projectId = sentry.getClient()?.getDsn()?.projectId;
      if (this.organization !== undefined && projectId !== undefined && event.event_id !== undefined) {
        properties.$sentry_url = new URL(
          `${this.organization}/issues/?project=${projectId}&query=${event.event_id}`,
          this.prefix ?? "https://sentry.io/organizations"
        ).toString();
      }

      this.posthog.capture({ event: "$exception", distinctId: userId, properties });

      return event;
    });
  }
}

I’d submit this as a PR, but it does have one small caveat—because posthog-node doesn’t store a persistent distinctId, we have to find it from somewhere. In my case, I keep the distinctId and the Sentry user.id in sync (with sentry.setUser({ id }) earlier in my code), but this obviously isn’t going to work for everyone. I am not entirely sure what a more robust solution would look like here, but it felt worth sharing what I had as a starting point.

`posthog-react-native` seems not to support web

I have an Expo app that also gets used by web browsers but posthog-react-native does not seem to recognize that or set itself up correctly.

As instructed by the Installation section and Configuration section, I've installed the required dependencies and setup PostHog as follows:

$ expo install posthog-react-native expo-file-system expo-application expo-device expo-localization
function MyApp() {
  return <NavigationContainer ... />
    <PostHogProvider apiKey={myKey} autocapture options={{ host: myHost }}>
      <MyNavigationStuffHere />
    </PostHogProvider>
  </NavigationContainer />
}

Nevertheless, I get the following error:

PostHog failed to persist data to storage Error: The method or property expo-file-system.writeAsStringAsync is not available on web, are you sure you've linked all the native dependencies properly?

I was able to reproduce this here: https://snack.expo.dev/@opiation/posthog-expo-web-bug

It seems like the new PostHog client does not handle the case where the platform is Web which is quite common for Expo projects. Is web supposed to be supported or are we expected to create a wrapper the web-only client and expo clients to choose the appropriate one ourselves depending on the platform?

Session recording for mobile apps

Just a question to evaluate if Posthog is right for us: is it planned to support session recording for mobile apps, either via the Android/iOS SDK or this library?

Upgrade target to es2020

Is your feature request related to a problem?

All built files are targeted es5, which compiles all async/await calls to some "polyfilled" version. This makes debugging PostHog quite hard as the stack traces are not complete. async/await has been supported for a long time and only breaks in IE11. Could I submit a PR upgrading the tsconfig.json to use es2020?

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Does not work on the Edge [Cloudflare Pages]

Bug description

Hello, I am trying to use posthog-node on the backend of Cloudflare pages.

How to reproduce

  1. Use posthog-node
  2. Deploy to Cloudflare Pages

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

This is the log I get when Cloudflare tries to build my app for its environment:

14:17:38.143 | > Using @sveltejs/adapter-cloudflare
14:17:38.260 | ✘ [ERROR] Could not resolve "crypto"
14:17:38.260 |  
14:17:38.260 | node_modules/posthog-node/lib/index.esm.js:1:27:
14:17:38.260 | 1 │ import { createHash } from 'crypto';
14:17:38.260 | ╵                            ~~~~~~~~
14:17:38.260 |  
14:17:38.260 | The package "crypto" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
14:17:38.261 |  
14:17:38.292 | ✘ [ERROR] Could not resolve "https"
14:17:38.292 |  
14:17:38.293 | node_modules/gaxios/build/src/gaxios.js:20:24:
14:17:38.293 | 20 │ const https_1 = require("https");
14:17:38.293 | ╵                         ~~~~~~~
14:17:38.293 |  
14:17:38.293 | The package "https" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
14:17:38.293 |  
14:17:38.294 | ✘ [ERROR] Could not resolve "querystring"
14:17:38.294 |  
14:17:38.294 | node_modules/gaxios/build/src/gaxios.js:22:46:
14:17:38.294 | 22 │ const querystring_1 = __importDefault(require("querystring"));
14:17:38.294 | ╵                                               ~~~~~~~~~~~~~
14:17:38.294 |  
14:17:38.294 | The package "querystring" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
14:17:38.295 |  
14:17:38.302 | ✘ [ERROR] Could not resolve "url"
14:17:38.302 |  
14:17:38.303 | node_modules/gaxios/build/src/gaxios.js:24:22:
14:17:38.303 | 24 │ const url_1 = require("url");
14:17:38.303 | ╵                       ~~~~~
14:17:38.303 |  
14:17:38.303 | The package "url" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
14:17:38.303 |  
14:17:38.318 | ✘ [ERROR] Could not resolve "net"
14:17:38.318 |  
14:17:38.319 | node_modules/https-proxy-agent/dist/agent.js:15:38:
14:17:38.319 | 15 │ const net_1 = __importDefault(require("net"));
14:17:38.320 | ╵                                       ~~~~~
14:17:38.320 |  
14:17:38.320 | The package "net" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
14:17:38.320 |  
14:17:38.321 | ✘ [ERROR] Could not resolve "tls"
14:17:38.321 |  
14:17:38.321 | node_modules/https-proxy-agent/dist/agent.js:16:38:
14:17:38.321 | 16 │ const tls_1 = __importDefault(require("tls"));
14:17:38.321 | ╵                                       ~~~~~
14:17:38.321 |  
14:17:38.321 | The package "tls" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
14:17:38.322 |  
14:17:38.322 | ✘ [ERROR] Could not resolve "url"
14:17:38.322 |  
14:17:38.322 | node_modules/https-proxy-agent/dist/agent.js:17:38:
14:17:38.322 | 17 │ const url_1 = __importDefault(require("url"));
14:17:38.322 | ╵                                       ~~~~~
14:17:38.322 |  
14:17:38.322 | The package "url" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
14:17:38.323 |  
14:17:38.323 | ✘ [ERROR] Could not resolve "assert"
14:17:38.323 |  
14:17:38.324 | node_modules/https-proxy-agent/dist/agent.js:18:41:
14:17:38.324 | 18 │ const assert_1 = __importDefault(require("assert"));
14:17:38.324 | ╵                                          ~~~~~~~~
14:17:38.324 |  
14:17:38.324 | The package "assert" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
14:17:38.324 |  
14:17:38.325 | ✘ [ERROR] Could not resolve "events"
14:17:38.325 |  
14:17:38.325 | node_modules/agent-base/dist/src/index.js:5:25:
14:17:38.325 | 5 │ const events_1 = require("events");
14:17:38.325 | ╵                          ~~~~~~~~
14:17:38.325 |  
14:17:38.326 | The package "events" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
14:17:38.326 |  
14:17:38.338 | error during build:
14:17:38.338 | Error: Build failed with 9 errors:
14:17:38.338 | node_modules/agent-base/dist/src/index.js:5:25: ERROR: Could not resolve "events"
14:17:38.338 | node_modules/gaxios/build/src/gaxios.js:20:24: ERROR: Could not resolve "https"
14:17:38.339 | node_modules/gaxios/build/src/gaxios.js:22:46: ERROR: Could not resolve "querystring"
14:17:38.339 | node_modules/gaxios/build/src/gaxios.js:24:22: ERROR: Could not resolve "url"
14:17:38.339 | node_modules/https-proxy-agent/dist/agent.js:15:38: ERROR: Could not resolve "net"
14:17:38.339 | ...
14:17:38.339 | at failureErrorWithLog (/opt/buildhome/repo/node_modules/esbuild/lib/main.js:1604:15)
14:17:38.339 | at /opt/buildhome/repo/node_modules/esbuild/lib/main.js:1056:28
14:17:38.339 | at /opt/buildhome/repo/node_modules/esbuild/lib/main.js:1001:67
14:17:38.339 | at buildResponseToResult (/opt/buildhome/repo/node_modules/esbuild/lib/main.js:1054:7)
14:17:38.339 | at /opt/buildhome/repo/node_modules/esbuild/lib/main.js:1166:14
14:17:38.340 | at responseCallbacks.<computed> (/opt/buildhome/repo/node_modules/esbuild/lib/main.js:701:9)
14:17:38.340 | at handleIncomingPacket (/opt/buildhome/repo/node_modules/esbuild/lib/main.js:756:9)
14:17:38.340 | at Socket.readFromStdout (/opt/buildhome/repo/node_modules/esbuild/lib/main.js:677:7)
14:17:38.340 | at Socket.emit (node:events:513:28)
14:17:38.340 | at addChunk (node:internal/streams/readable:315:12)
14:17:38.369 | Failed: build command exited with code: 1
14:17:39.276 | Failed: an internal error occurred

Add debug mode

This is a great library, particularly for places where you're really constrained for bundle size. Would be great if we could add debug mode as we have in posthog-js to make sure your event instrumentation is right.

Add a way to filter debug logging based on a given debugLevel in posthog-react-native

Is your feature request related to a problem?

When using <PostHogProvider apiKey={...} debug={__DEV__}>, PostHog produces absurd amounts of logging with "PostHog Debug" messages, especially if you have heavy instrumentation. This is very distracting and can hide more important log messages.

Describe the solution you'd like

Add an option to PostHogProvider like quiet or loggingEnabled={false} that can be used to disable the logging.

Describe alternatives you've considered

  • Writing really gross JSX workarounds
  • Patching the package with patch-package (currently doing this)

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

<3

RN: Document Wix navigation support

Is your feature request related to a problem?

The current PostHogProvider assumes either a typical React Native app or one using https://reactnavigation.org/ but some customers are using Wix's navigation which breaks from the typical declarative view structure of React with multiple "scenes".

This means autocapture and navigation and lifecycle events don't work as you can't have a global provider (I think) and the view hierarchy is completely different.

Describe the solution you'd like

At the very least, document how a Wix navigating app should work with PostHog.

Best case, extend the SDK to have an easy-to-use implementation that makes it as straightforward as possible to work with that SDK.

Describe alternatives you've considered

Related sub-libraries

  • posthog-react-native

Additional context

Thank you for your feature request – we love each and every one!

Improve/add support for sync providers, ie rn-mmkv

Is your feature request related to a problem?

Would be nice if we could use MMKV instead of async storage

Describe the solution you'd like

Describe alternatives you've considered

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your feature request – we love each and every one!

Massive slowdown in using shutdownAsync vs shutdown

Bug description

Not sure if this has to do with some issue on the ingestion level or something but recently we noticed that calling await posthog.shutdownAsync() was holding up the execution thread for around 9 seconds! Switching from shutdownAsync to just shutdown seemed to fix the issue.

We're deploying in Next.js using vercel so under the hood these are either edge functions or AWS lambda functions. I think in this case it's an edge function.

How to reproduce

  1. Follow the advice of setting flushAt to 1, flushInterval to 0, and calling shutdownAsync() https://posthog.com/docs/libraries/node#options.
  2. Call shutdownAsync after capturing an event
  3. Experience a 9 second hang time that isn't present on the non-async shutdown version of the call

Related sub-librarie

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

I think this issue might relate to edge functions on vercel. Additionally from digging into the source code, it seems like this is the only difference between the versions in posthog-node.ts:

shutdown(): void {
   void this.shutdownAsync()
}

async shutdownAsync(): Promise<void> {
    this.featureFlagsPoller?.stopPoller()
    return super.shutdownAsync()
}

So maybe it's an issue with feature flags?

Also more than possible this is a user issue and it's something I'm doing wrong. We recently moved to vercel and started noticing this slowing us down...

React Native app tested with jest fails with: PostHog: No storage available. Please install expo-filesystem or react-native-async-storage OR implement a custom storage provider.

Bug description

When trying to test a react native app with PostHog installed, the following error is thrown:
Error: PostHog: No storage available. Please install expo-filesystem or react-native-async-storage OR implement a custom storage provider. at buildOptimisiticAsyncStorage even though async storage is installed

How to reproduce

  1. create a new react native project with npx react-native@latest init AwesomeProject as mentioned in the docs
  2. Install with yarn add posthog-react-native @react-native-async-storage/async-storage react-native-device-info and configure posthog
  3. run yarn test -> Fails

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your bug report – we love squashing them!

React native feature flag payload

Describe the solution you'd like

Support for feature flags payloads.

If the core supports it, seems it could be a simple and easy addition to react-native library

Describe alternatives you've considered

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your feature request – we love each and every one!

"Possible Unhandled Promise Rejection" when offline

Bug description

Without internet access, the client will eventually warn about an Possible Unhandled Promise Rejection.

I'm guessing this is a minor issue - but still, it is:

  1. A possible risk of misbehavior
  2. Annoying

I at least wish for a way of silencing these warnings, but maybe also a new option property (called onFetchError?) for handling these situations.

How to reproduce

  1. Set the client.options.fetchRetryCount to 0 (optional)
  2. Run a basic local instance of ReactNative that implements PostHogProvider
  • I have only tested on ios simulator, but it should be the same on android.
  1. Turn off the internet on your computer
  2. The warning should appear within a few seconds

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your bug report – we love squashing them!

React Native Web and `expo-file-system` support

Description

https://github.com/necolas/react-native-web#readme

RN Web is getting more popular but our SDK does not support it yet, at least not without workarounds.

The goal of this issue is to list all the issues encountered and at least make the changes to run the SDK on RN Web without any compile/runtime issues, even if some features have to be disabled.

Issues faced as of now:

Expo universal app's web target should not use expo-file-system

Bug description

We are integrating Posthog in our stack and ran into this case where the web target is not handled by the Posthog react-native library properly.

How to reproduce

  1. Create a Expo universal app
  2. Build and run the web target
  3. Error

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your bug report – we love squashing them!

posthog-node v2.3.0 imports types from posthog-core without a dependency

Bug description

posthog-node v2.3.0 updated the types to import from posthog-core/src, but posthog-core is not listed as a dependency. This causes typescript builds to fail with the error "Cannot find module 'posthog-core/src' or its corresponding type declarations"

import { JsonType } from 'posthog-core/src'

How to reproduce

  1. Install posthog-node
  2. Try to build with typescript

Related sub-libraries

  • All of them
  • posthog-web
  • posthog-node
  • posthog-react-native

Additional context

Thank you for your bug report – we love squashing them!

Allow persisting distinct IDs

Right now distinct IDs are generated automatically and not stored so even after a refresh, we think the browser is now a different user.

Happy to create a PR for this but would love some 👀 with tests.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.