Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch adapter #304

Open
AvivonCtrl opened this issue Aug 9, 2021 · 21 comments
Open

Fetch adapter #304

AvivonCtrl opened this issue Aug 9, 2021 · 21 comments

Comments

@AvivonCtrl
Copy link

Fetch instead of XHR for ServiceWorker compatibility

@gmuresan
Copy link

gmuresan commented Apr 7, 2022

It looks like mixpanel no longer works in service workers for v3 chrome extensions. XHR has been deprecated/removed and fetch is now required. Are there any plan to migrate to fetch, or is there a workaround for service workers?

@juanfer0002
Copy link

Does anyone have an update about this?

@juanfer0002
Copy link

juanfer0002 commented Oct 21, 2022

For whoever came here looking for answers, and found none, feel free to use this code.

I implemented fetch provisionally, while there's an official answer. I tested in development, and it is working so far.

@lukafilipov
Copy link

Thank you @juanfer0002 for adding this! It's funny how the library just silently stops working with manifest v3. @tdumitrescu any idea if/when the PR juanfer created will be reviewed and merged?

@juanfer0002
Copy link

@lukafilipov Since you're using this with the manifest v3, I have to warn you to be extremely careful when reporting to Mixpanel as service workers get shutdown by Chrome every five minutes.

This means that if you have identified a user, all events will be associated to them, but after 5m this identification will be lost, making every event not being correctly associated.

We had to implement a system to handle this situation, you may end up in a similar one.

@lukafilipov
Copy link

lukafilipov commented Jan 12, 2023

@juanfer0002 Got it, thanks for the heads up! And thanks again for the fix, I've tested it and it just works out of the box. I have referenced your branch directly from package.json like this:
"mixpanel-browser": "juanfer0002/mixpanel-js-mv3#fetch-support-for-mv3-extensions",

@spookyuser
Copy link

@juanfer0002 I love you

@aamirv
Copy link

aamirv commented Mar 3, 2023

Thank you for working on this @juanfer0002. I am wondering if you have encountered these issues (happy to talk privately -what's the best way to do that?):

  1. you mentioned that this can get running with a service worker, but it will shut down. YES, and that causes Mixpanel to see the result as different users as a result, like you said. So I thought the best practice would be to send a message back to background.js and talk to mixpanel there. Is that right?
  2. related to this idea - how are you getting it into background.js? I see references to document and window, so that doesn't work.

I get this error right now: "Uncaught TypeError: Cannot set property navigator of # which has only a getter". I can comment out the line, but not sure what that is really doing.

Did you consider shifting to the HTTP API? I'm wondering if using mixpanel is worth it.

For those working on Chrome extensions.... how are you doing user tracking to learn how they are using product?

(I kind of doubt this will get merged into the main - is that right @tdumitrescu or anyone at mixpanel?)

@spookyuser
Copy link

spookyuser commented Mar 4, 2023

Take a look at this class @aamirv it helped me a lot, I don't think you have to run it in the background but idk, on plasmo I just made this class and imported it and everything's working so might be running in the background actually.

@juanfer0002
Copy link

@aamirv You can just import files in the background js with normal JS syntax, and then use it as an object. LMK if you need a more precise example, I am responding from my phone.

Regarding the other issue, when the SW shuts down, be aware that the callbacks and events are still being fired by Chrome when the port closes, in such a case I Just retry the connection with the service worker.

@rahulbansal16
Copy link

"mixpanel-browser": "juanfer0002/mixpanel-js-mv3#fetch-support-for-mv3-extensions",

so just updating the package.json file will work? No other code change require?

@gigabrain-kabir
Copy link

Is this expected to be added to a mixpanel-js release?

@neecto
Copy link

neecto commented Aug 31, 2023

any updates on this? It's tagged as "enhancement" but it's really a bug that makes mixpanel-browser unusable in chrome extensions

@NorbertBodziony
Copy link

Seems like real issue right now

@Kitenite
Copy link

Kitenite commented Apr 9, 2024

Bump, this is still an issue in V3

@kyranjamie
Copy link

Very limiting for Web Extension users of Mixpanel.

@revmischa
Copy link

I need to use this in a chrome extension and I'm getting an error unless I use juanfer0002:fetch-support-for-mv3-extensions

@doc-han
Copy link

doc-han commented Apr 18, 2024

Want to use mixpanel for your extension? The easiest way is to write your own code.

Reasons

  1. Mixpanel-js uses a synchronous storage. You lack that in extension service worker.
  2. Mixpanel-js depends on some DOM api's you don't have access to in the service worker.
  3. Mixpanel-js doesn't support asynchronous init which you need because of [1]
  4. Mixpanel-js uses xhr instead of fetch? Sorry you only have fetch in the extension service worker

Solution

Note: Doesn't support batch processing!
A simple one file drop replacement. You can edit anyhow you want! No need to install any package into your extension.

Supports init, identify, reset and track.
All these functions are asynchronous and uses chrome.storage.local for $device_id and $user_id storage
Below is the GIST
https://gist.github.com/doc-han/6c998058744eebafc43c132bdc28bd00

Usage

The typescript code in the GIST returns an object called tracker.

Hence, all you do is use that object whenever you need. Example

// inside an extension service worker
import tracker from "./mixpanel-chrome" // importing from the gist file copy-and-pasted

// initializing mixpanel
tracker.init("<mixpanel-project-id>")

chrome.runtime.onInstalled.addListener((details) => {
	// tracking extension install
	tracker.track("install", {
		extensionVersion: chrome.runtime.getManifest().version
	})
})

function signUp(){
	const user = getSignUpUser(); // gets signed up user
	tracker.identify(user.uid); // mixpanel identify
}

function logout(){
	tracker.reset(); // mixpanel user reset on logout
}

Visit the Gist
Danke!

@spookyuser
Copy link

spookyuser commented Apr 19, 2024

I disagree if you use a patch like this in pnpm

diff --git a/dist/mixpanel.cjs.js b/dist/mixpanel.cjs.js
index 1aa8b28066511a67802cb14afd820e0d76c446b3..5a0be18ca9ec10ef3a22bbcbe7ece168b01b3aa5 100644
--- a/dist/mixpanel.cjs.js
+++ b/dist/mixpanel.cjs.js
@@ -1,3 +1,5 @@
+import XMLHttpRequest from 'xhr-shim';
+
 'use strict';
 
 var Config = {
@@ -3204,7 +3206,11 @@ MixpanelPeople.prototype.set = addOptOutCheckMixpanelPeople(function(prop, to, c
     }
     // make sure that the referrer info has been updated and saved
     if (this._get_config('save_referrer')) {
-        this._mixpanel['persistence'].update_referrer_info(document.referrer);
+        try{
+            this._mixpanel['persistence'].update_referrer_info(document.referrer);
+        } catch {
+            console.warn("Failed to update referrer info")
+        }
     }
 
     // update $set object with default people properties
@@ -4129,7 +4135,7 @@ var NOOP_FUNC = function() {};
  */
 // http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/
 // https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#withCredentials
-var USE_XHR = (window$1.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest());
+var USE_XHR = true
 
 // IE<10 does not support cross-origin XHR's but script tags
 // with defer won't block window.onload; ENQUEUE_REQUESTS
diff --git a/package.json b/package.json
index 0141403fb5b537a8649aa0a1ac6df675a46965d1..8db641b7f5bc28f1eecacb94ac42bfb1555afa79 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,9 @@
     "url": "https://github.com/mixpanel/mixpanel-js/issues"
   },
   "homepage": "https://github.com/mixpanel/mixpanel-js",
+  "dependencies": {
+    "xhr-shim": "0.1.3"
+  },
   "devDependencies": {
     "babel": "6.5.2",
     "babel-core": "6.7.2",

which adds xhr-shim to mixpanel it works with the most recent versions in chrome-mv3

@revmischa
Copy link

I'm using @doc-han's nice mixpanel client in my extension. I have some mixpanel shared code between the webapp and extension so I instruct webpack to swap out mixpanel-browser for the extension version behind the scenes when building the extension:

resolve: {
    alias: {
      // use chrome extension version of mixpanel client
      "mixpanel-browser": resolve(webpackExtSrcDir, "api", "mixpanelExtension.ts"),
    },
  },

@brloman
Copy link

brloman commented Aug 2, 2024

Did anybody else face the error 'document undefined' when trying to load Mixpanel in an MV3 extension?

The code part that is causing the issue is mixpanel.cjs.js line 11079.

Uploading Screenshot 2024-08-02 at 09.52.28.png…
Uploading Screenshot 2024-08-02 at 09.52.20.png…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests